C++函数声明和对象初始化的区别

标签 c++ c++11

如果我写这行代码:

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/

相关文章:

c++ - openCV 2.4.3 iOS 框架编译器无法识别某些 C++ header

c++ - 如何应对无限可能的结果?

android - Android NDK 中的 u16string 和 char16_t

c++ - 如何声明实例化 `emplace()` 的 `std::set` 的返回?

c++ - 更改文件内容 - 这是 g++ 4.7.2 中的错误还是我做错了?

c++ - 具有多个类对象的 vector 会产生编译错误?

c++ - 错误 : The term 'bootstrap-vcpkg.bat' is not recognized : While Install C and C++ libraries for Visual Studio 2017 on Win10

c++ - 实现上下文切换 - 第二个功能不再运行

c++ - 使用不同的新表达式语法创建对象有什么区别

c++ - 这个 C++/C++11 结构是什么意思?