如果我写这行代码:
std::thread t(EchoServer(socket));
编译器如何解释这条指令?它可以是一个函数声明或只是一个初始化。 我有以下代码:
#include <iostream>
#include <thread>
#include <boost/asio.hpp>
#include <boost/asio.hpp>
typedef boost::asio::ip::tcp::socket Socket;
auto socket_deleter = [] (Socket* s) {s->close(); delete s;};
typedef std::unique_ptr<Socket, decltype(socket_deleter)> socket_ptr;
class EchoServer {
public:
static void Listen(unsigned int port)
{
using namespace std;
using namespace boost::asio;
io_service ios;
// create an endpoint to listen to a certain port
ip::tcp::endpoint endpoint(ip::tcp::v4(), port);
cout << "Listening to TCP Socket on port " << port << " ..." << endl;
// Start opening a socket
ip::tcp::acceptor acceptor(ios, endpoint);
// this loop must be infinite... but we accept only 3 connections
auto socket = socket_ptr(new Socket(ios));
std::thread t(EchoServer(socket));
}
EchoServer(socket_ptr&& s) : m_socket(std::move(s))
{
}
void operator ()() const
{
}
private:
socket_ptr m_socket;
};
但是编译器给我以下警告:
C4930: 'std::thread t(EchoServer(socket))': std::thread t(EchoServer(socket)) function not called (was a variable definition intended?).
那么我如何解释这一行是一个 std::thread 类型的对象创建而不是一个函数声明。
更新 1:
我正在使用不支持统一初始化的 visual studio 2012,所以我将代码从 std::thread t((EchoServer(socket)));
更改为 std::线程 t((EchoServer(socket)));
但这次我有一个我不明白的编译时错误:
error C2440: '<function-style-cast>': cannot convert from 'std::unique_ptr<_Ty,_Dx>' to 'EchoServer'
我错过了什么?
更新 2 我可能必须更好地理解移动语义,问题在于 socket_ptr 的声明。我已经以这种(丑陋的)方式更改了代码……但现在可以编译了。
#include <iostream>
#include <thread>
#include <boost/asio.hpp>
typedef boost::asio::ip::tcp::socket Socket;
auto socket_deleter = [] (Socket* s) {s->close(); delete s;};
/*
typedef std::unique_ptr<Socket, decltype(socket_deleter)> socket_ptr;
*/
typedef Socket* socket_ptr;
class EchoServer {
public:
static void Listen(unsigned int port)
{
using namespace std;
using namespace boost::asio;
io_service ios;
// create an endpoint to listen to a certain port
ip::tcp::endpoint endpoint(ip::tcp::v4(), port);
cout << "Listening to TCP Socket on port " << port << " ..." << endl;
// Start opening a socket
ip::tcp::acceptor acceptor(ios, endpoint);
// this loop must be infinite... but we accept only 3 connections
auto socket = new Socket(ios);
std::thread t((EchoServer(socket)));
}
EchoServer(socket_ptr s) : m_socket(s)
{
}
~EchoServer()
{
m_socket->close();
delete m_socket;
}
void operator ()() const
{
}
private:
socket_ptr m_socket;
};
将 socket_ptr 更改为一个简单的指针,而不是 unique_ptr 代码可以正常工作。
最佳答案
这是一个函数声明。如果要声明一个直接初始化的对象,可以使用以下方法之一:
std::thread t(EchoServer { socket });
std::thread t { EchoServer(socket) };
std::thread t { EchoServer { socket} };
std::thread t((EchoServer(socket)));
Brace-initialization 是明确的初始化,在最后一行你有一个带括号的表达式,它不能作为函数参数声明。
关于C++函数声明和对象初始化的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13734262/