開いているソケットにメッセージを送信するためにスレッドを作成しようとしています。2つの特定のエラーが発生します。
E0289:コンストラクター "std :: thread :: thread"のインスタンスが引数リストに一致しません。
C2661: 'std :: thread :: thread'オーバーロードされた関数は2つの引数を取りません**
私はこれについて同様の投稿を見つけましたが、それでもそれが実際にいくつかの説明を使用できることを完全に理解することはできません。
#include <WS2tcpip.h>
#include <string>
#include <thread>
using namespace std;
#pragma comment (lib, "ws2_32.lib")
void SendMessage(string message)
{
WSAData data;
WORD version = MAKEWORD(2, 2);
int wsOk = WSAStartup(version, &data);
if (wsOk != 0)
{
cout << "Failed, Error Code: " << WSAGetLastError() << endl;
}
sockaddr_in user;
user.sin_family = AF_INET;
user.sin_port = htons(3514);
inet_pton(AF_INET, "127.0.0.1", &user.sin_addr);
SOCKET out = socket(AF_INET, SOCK_DGRAM, 0);
int sendMsg = sendto(out, message.c_str(), message.size() + 1, 0, (sockaddr*)&user, sizeof(user));
if (sendMsg == SOCKET_ERROR)
{
cout << "Failed, Error: " << WSAGetLastError() << endl;
}
closesocket(out);
WSACleanup();
}
int main()
{
string message = "";
cout << "Enter a message to send: ";
cin >> message;
thread sendtoSocket (SendMessage, message);
sendtoSocket.join();
system("pause");
return 0;
}
Windowsには、SendMessage
Unicodeが有効になっているかどうかに応じてSendMessageA
、SendMessageW
関数と関数を透過的に切り替えるマクロがあります。このマクロ置換はあなたのSendMessage
機能を踏みにじっています。
あなたは付け加えられます
#undef SendMessage
後のどこでも
#include <WS2tcpip.h>
しかし、これは後で問題を引き起こす可能性があります。SendMessage
関数の名前を衝突しない名前に変更するのが最善だと思います。
なぜこれが問題なのですか?あいまいさ。これをMCVEにハックしてみましょう。
#include <WS2tcpip.h>
#include <string>
#include <thread>
#include <iostream>
using namespace std;
void SendMessage(string /*message*/)
{
}
int main()
{
string message = "Test";
thread sendtoSocket (SendMessage, message);
sendtoSocket.join();
}
プリプロセッサの後、プログラムは次のようになります
void SendMessageW(string /*message*/)
{
}
int main()
{
string message = "Test";
thread sendtoSocket (SendMessageW, message);
sendtoSocket.join();
}
コンパイラは、どのSendMessageW
オーバーロードを呼び出すthread sendtoSocket (SendMessageW, message);
必要があるか、askerまたはWin32 API関数を把握する必要がありますが、それはできません。これにより、コンパイラは追加のスレッドコンストラクタを検索し、誤解を招く診断が生成されます。
それがどうなっているのかを調べると、テンプレート化された関数のオーバーロードがない、さらに単純なMCVEが必要です。
void A(int )
{
}
void A(double )
{
}
template<typename FUNC, typename... ARGS>
void test(FUNC&& func, ARGS&&... args)
{
func(args...);
}
int main()
{
int message = 10;
test(A, message);
}
これにより、意味のある診断が行われます。
エラーC2672: 'テスト':一致するオーバーロードされた関数が見つかりません
エラーC2783: 'void test(FUNC &&、ARGS && ...)': 'FUNC'のテンプレート引数を推測できませんでした
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加