【问题标题】:Compiler compile a 'io_service_' variable show as : cannot appear in a constant-expression编译器编译“io_service_”变量显示为:不能出现在常量表达式中
【发布时间】:2011-08-07 14:37:34
【问题描述】:

我创建了一个包含类名 server_datetime 的 ServerService 命名空间。 Server_datetime 类作为 Boost 示例中的教程,但我通过使用模板参数将 io_service ( boost::asio::io_service ) 和端点 ( tcp::endpoint(tcp::v4(),SIZE_DATA) ) 对象插入模板改进了 server_datetime 类.我按照下面的例子:

using boost::asio::ip::tcp;
namespace ServerService{
template<typename Service, typename Endpoint>
class server_datetime {
public:
    server_datetime(){
        acceptor_(service_, endpoint_);
        for(;;)
        {
            tcp::socket socket(Service);
            acceptor_.accept(socket);
            std::string message = make_daytime_string;

            boost::system::error_code ignored_error;
            boost::asio::write(socket, boost::asio::buffer(message),boost::asio::transfer_all(), ignored_error);
        }
    }
    std::string make_daytime_string(){
        std::time_t now = std::time(0);
        return std::ctime(&now);
    }
    virtual ~server_datetime();
private:
    tcp::acceptor acceptor_;
    Service service_;
    Endpoint endpoint_;
};
}

调用server_datetime类的主函数如下:

#include "server_datetime.hpp"
using namespace std;
using boost::asio::ip::tcp;
int main() {
    const boost::asio::io_service io_service_;
    const int SIZE_DATA = 13;
    ServerService::server_datetime<io_service_, tcp::endpoint(tcp::v4(),SIZE_DATA)  >  server;
    cout << "" << endl; // prints 
    return 0;
}

编译器编译main函数后,编译器显示错误为:

..\src\connectk.cpp: In function 'int main()':
..\src\connectk.cpp:10: error: 'io_service_' cannot appear in a constant-expression
..\src\connectk.cpp:10: error: 'boost::asio::ip::tcp::v4()' cannot appear in a constant-expression
..\src\connectk.cpp:10: error: a function call cannot appear in a constant-expression
..\src\connectk.cpp:10: error: template argument 1 is invalid
..\src\connectk.cpp:10: error: template argument 2 is invalid
..\src\connectk.cpp:10: error: invalid type in declaration before ';' token

【问题讨论】:

    标签: c++ templates parameters non-type


    【解决方案1】:

    模板参数用于在编译时指定类型和常量值,而不是在运行时注入对象;这就是普通函数/构造函数参数的用途。因此,在这种情况下,如果您向服务器提供服务和端点,请将它们作为参数传递给构造函数。

    代码中还有一些其他错误;这里有一些更正(虽然可能还有问题,我自己可能已经介绍了一些):

    namespace ServerService{
    
    // Put 'using' declarations inside the namespace,
    // to avoid polluting the global namespace
    using boost::asio::ip::tcp;
    using boost::asio::io_service;
    
    // Not a template - pass runtime objects as constructor arguments
    class server_datetime {
    public:
        server_datetime(io_service & service, tcp::endpoint const & endpoint) :
            // Initialise members in an initialiser list
            acceptor_(service, endpoint),
            service_(service)
        {}
    
        // Put the main loop in a separate function; it's rather odd
        // to have a constructor that doesn't return.
        void run(){
            for(;;)
            {
                // Argument must be the object service_, not the type Service
                tcp::socket socket(service_); 
                acceptor_.accept(socket);
                std::string message = make_daytime_string(); // missing parentheses
    
                boost::system::error_code ignored_error;
                boost::asio::write(socket, boost::asio::buffer(message),boost::asio::transfer_all(), ignored_error);
            }
        }
        std::string make_daytime_string(){
            std::time_t now = std::time(0);
            return std::ctime(&now);
        }
        // No need for a virtual destructor - this class is not polymorphic
    private:
        boost::asio::io_service & service_; // must be a reference - io_service is not copyable
        tcp::acceptor acceptor_;
        // No need to store the endpoint - it's only used to initialise acceptor_.
    };
    }
    
    int main() {
        using boost::asio::ip::tcp;
    
        // can't be const if you want to use it
        boost::asio::io_service io_service_;
    
        // renamed SIZE_DATA and given it the same type as the constructor argument
        const unsigned short port = 13; 
    
        ServerService::server_datetime server(io_service_, tcp::endpoint(tcp::v4(),port));
        server.run();
        // no need to explicitly return zero, unless you want to.
    }
    

    【讨论】:

    • 我可以使用模板参数列表是“类”吗?比如'template'如果我想注入对象。 link
    • @Chatsiri.rat: 不,在模板参数列表中class 的含义与typename 相同;两者都声明了一个类型参数。模板是在编译时实例化的,因此您可以注入的唯一对象是编译时常量。如果要注入运行时对象,则必须通过函数或构造函数参数来完成。
    • 我将 main 方法分配给类文件,将 ServerService 命名空间分配给头文件。为什么编译器显示无法创建在类文件上实例化的服务器?
    • @Chatsiri.rat:因为我在代码中犯了几个错误。我刚刚更正了它,虽然可能还有更多错误。
    • 我通过改进服务器实例化类来解决类文件中主要功能的问题ServerService::server_datetime server(io_service_, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),port) ); server.run();
    【解决方案2】:
    std::string message = make_daytime_string;
    

    你忘记了(),应该是:

     std::string message = make_daytime_string();
    

    【讨论】:

      【解决方案3】:

      server_datetime 模板需要类型名称(它在第一个源代码的顶部这么说),但您提供了值。

      也许你不应该在 main 中创建 io_service_,而是让服务器来做?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-06
        • 1970-01-01
        • 2022-11-15
        • 2018-02-28
        • 2012-12-26
        • 1970-01-01
        • 2013-07-04
        相关资源
        最近更新 更多