如何为不同的模板参数创建不同的构造函数? `requires` 关键字不起作用

问题描述 投票:0回答:1

我正在尝试创建类

ServerLogic
,其中构造函数根据模板参数获取不同的参数并以不同的方式处理它(在这种情况下它将它们传递给
endpoint
构造函数)

// Shortened version of code
using namespace boost::asio;

template <typename Protocol>
class ServerLogic
{
    static_assert(
        std::is_same_v<Protocol, local::stream_protocol> ||
        std::is_same_v<Protocol, ip::tcp>
    ); // Allow using only either `local::stream_protocol` or
       // `local::tcp` as Protocol
    Protocol::endpoint *ep;
public:
    ServerLogic(std::string sock_path)
        requires std::is_same<Protocol, local::stream_protocol>::value
        : ep(new Protocol::endpoint(sock_path))
        {} // If Protocol is `local::stream_protocol` then create ep of
           // `local::stream_protocol` due to it's constructor
    ServerLogic(const ip::address &addr, unsigned short port)
        requires std::is_same<Protocol, ip::tcp>::value
        : ep(new Protocol::endpoint(addr, port))
        {} // If Protocol is `ip::tcp` then create ep of `ip::tcp` protocol
           // due to it's constructor, different from `local::stream_protocol`
           // endpoint constructor

但是编译器给出了错误:

[build] /home/shkiperdesna/cppbot/src/ServerLogic.hpp: In instantiation of ‘ServerLogic<Protocol>::ServerLogic(const boost::asio::ip::address&, short unsigned int) requires  is_same_v<Protocol, boost::asio::ip::tcp> [with Protocol = boost::asio::local::stream_protocol]’:
[build] /home/shkiperdesna/cppbot/src/ServerLogic.cpp:95:16:   required from here
[build] /home/shkiperdesna/cppbot/src/ServerLogic.hpp:49:14: error: no matching function for call to ‘boost::asio::local::basic_endpoint<boost::asio::local::stream_protocol>::basic_endpoint(const boost::asio::ip::address&, short unsigned int&)’

...

我知道,尽管使用了

requires
关键字,编译器仍尝试使用两种协议来编译两个构造函数。如何解决这个问题并为不同的模板参数拆分构造函数?

c++ class templates constructor
1个回答
0
投票

另请参阅:如何禁用某些模板类型的类成员函数

您的问题是您的要求不依赖于成员函数的任何模板参数,而是依赖于整个类。因此,即使

new Protocol::endpoint(addr, port)
不满足,也会检查
requires std::is_same<Protocol, ip::tcp>::value

你必须将构造函数设为模板:

template <typename Protocol>
class ServerLogic
{
    static_assert(
        std::is_same_v<Protocol, local::stream_protocol> ||
        std::is_same_v<Protocol, ip::tcp>
    ); // Allow using only either `local::stream_protocol` or
       // `local::tcp` as Protocol
    Protocol::endpoint *ep;
public:
    template<typename U = Protocol>
    ServerLogic(std::string sock_path)
        requires std::is_same<U, local::stream_protocol>::value
        : ep(new U::endpoint(sock_path))
        {} // If Protocol is `local::stream_protocol` then create ep of
           // `local::stream_protocol` due to it's constructor
    template<typename U = Protocol>
    ServerLogic(const ip::address &addr, unsigned short port)
        requires std::is_same<U, ip::tcp>::value
        : ep(new U::endpoint(addr, port))
        {} // If Protocol is `ip::tcp` then create ep of `ip::tcp` protocol
           // due to it's constructor, different from `local::stream_protocol`
           // endpoint constructor
© www.soinside.com 2019 - 2024. All rights reserved.