gpt4 book ai didi

c++ - std::thread 通过引用传递调用复制构造函数

转载 作者:IT老高 更新时间:2023-10-28 12:46:40 26 4
gpt4 key购买 nike

嗯,我在使用 std::thread 将数据传递到线程时遇到了问题。我以为我理解了复制构造函数等的一般语义,但似乎我不太明白这个问题。我有一个名为 Log 的简单类,因此隐藏了它的复制构造函数:

class Log
{
public:
Log(const char filename[], const bool outputToConsole = false);
virtual ~Log(void);

//modify behavior
void appendStream(std::ostream *);
//commit a new message
void commitStatus(const std::string str);

private:
//members
std::ofstream fileStream;
std::list<std::ostream *> listOfStreams;

//disable copy constructor and assignment operator
Log(const Log &);
Log & operator=(const Log &);
}

现在我有一个主要基于 http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp11/echo/blocking_tcp_echo_server.cpp

int main()
{
static int portNumber = 10000;

Log logger("ServerLog.txt", true);
logger.commitStatus("Log Test String");

try {
boost::asio::io_service ioService;
server(ioService, portNumber, logger);
}
catch (std::exception &e)
{
std::cerr << "Exception " << e.what() << std::endl;
logger.commitStatus(e.what());
}

return 0;
}

可以看到main调用了函数server,传递了IOService、portNumber和logger。记录器是通过引用传递的,因此:

using boost::asio::ip::tcp;

void server(boost::asio::io_service &ioService, unsigned int port, Log &logger)
{
logger.commitStatus("Server Start");

tcp::acceptor acc(ioService, tcp::endpoint(tcp::v4(), port));

while(true)
{
tcp::socket sock(ioService);
acc.accept(sock);

std::thread newThread(session, &sock, logger);
newThread.detach();
}

logger.commitStatus("Server closed");
}

当我尝试通过引用将记录器(或套接字)传递给线程时出现编译器错误,但在通过引用将其传递给 session() 时没有得到错误

static void session(tcp::socket *sock, Log &logger)
{
std::cout << " session () " << std::endl;
}

现在我认为我正确理解了引用与传递指针相同。也就是说,它不调用复制构造函数,它只是传递指针,它让您在语法上将其视为不是指针。

error C2248: 'Log::Log' : cannot access private member declared in class 'Log'

1> \log.h(55) : see declaration of 'Log::Log'

1> \log.h(28) : see declaration of 'Log'

...

: see reference to function template instantiation 'std::thread::thread(_Fn,_V0_t &&,_V1_t)' being compiled

1> with

1> [

1> Fn=void (_cdecl *)(boost::asio::ip::tcp::socket *,Log &),

1> _V0_t=boost::asio::ip::tcp::socket *,

1> _V1_t=Log &

1> ]

但是,如果我修改它以传递指针,一切都会很愉快

...
std::thread newThread(session, &sock, &logger);
...

static void session(tcp::socket *sock, Log *logger)
{
std::cout << " session () " << std::endl;
}

为什么要通过引用传递调用我的复制构造函数。由于std::thread,这里发生了什么特别的事情吗?我是否误解了复制构造函数并通过引用传递?

如果我尝试像示例中那样使用 std::move() ,我会得到一个不同但同样令人困惑的错误。有没有可能我的 VS2012 没有正确实现 C++11?

最佳答案

std::thread 按值获取参数。您可以使用 std::reference_wrapper:

来获取引用语义
std::thread newThread(session, &sock, std::ref(logger));

显然你必须确保 logger 比线程长。

关于c++ - std::thread 通过引用传递调用复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21048906/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com