如果可能的话,如何将enable_if_t模板限制应用于具有单独实现代码的整个类?

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

注意:我更喜欢始终将我的实现与我的声明分开,即使对于仍然必须放在标头中的模板代码也是如此。因此,我倾向于使用一个用于声明的

.h
文件,并在该文件的底部包含一个用于内联和模板实现的
.hpp
文件,然后将我的非内联、非模板实现放入
.cpp
文件中。在这种情况下,可能无法遵循该偏好,或者我可能做错了什么。

我有这个初始类声明:

template<class TAddress>
class OddSource_Export InterfaceIPAddress
{
public:
    InterfaceIPAddress(TAddress const &, uint16_t);
    ...
private:
    ::std::unique_ptr<TAddress> const _address;
    uint16_t const _flags;
}

然后这个构造函数实现就可以工作,并且使用此类的代码可以编译:

template<class TAddress>
InterfaceIPAddress<TAddress>::
InterfaceIPAddress(TAddress const &address, uint16_t flags)
    : _address(new TAddress(address)),
      _flags(flags)
{
}

但我想要一个简单的基类限制。所以我首先定义这个别名:

template<class TAddress>
using Enable_If_IPAddress = ::std::enable_if_t<::std::is_base_of_v<IPAddress, TAddress>>;

更改我的类声明如下:

template<class TAddress, typename = Enable_If_IPAddress<TAddress>>
class OddSource_Export InterfaceIPAddress
...

并将我的构建实现更改如下:

template<class TAddress, typename>

但是,现在我的构造函数无法编译:

warning: missing 'typename' prior to dependent type name InterfaceIPAddress<TAddress>::InterfaceIPAddress; implicit 'typename' is a C++20 extension [-Wc++20-extensions]
    InterfaceIPAddress<TAddress>::
    ^
    typename 
error: expected ')'
    InterfaceIPAddress(TAddress const &address, uint16_t flags)
                                ^
note: to match this '('
    InterfaceIPAddress(TAddress const &address, uint16_t flags)
                      ^
error: expected ';' at end of declaration
        : _address(new TAddress(address)),
        ^
        ;
error: no template named '_address'; did you mean 'TAddress'?
        : _address(new TAddress(address)),
          ^~~~~~~~
          TAddress
...

我非常确定我正确定义了

enable_if_t
,因为如果我将实现移动到与声明内联,它会在没有警告或错误的情况下进行编译:

template<class TAddress, typename = Enable_If_IPAddress<TAddress>>
class OddSource_Export InterfaceIPAddress
{
public:
    InterfaceIPAddress(TAddress const & address, uint16_t flags)
        : _address(new TAddress(address)),
          _flags(flags)
    {
    }
    ...
private:
    ::std::unique_ptr<TAddress> const _address;
    uint16_t const _flags;
};

那么我是否错过了分离实施所需的一些额外步骤?或者使用

enable_if_t
时是否无法分离此实现?

编辑1

出于复制目的:

... above code ...

class IPAddress {};
class IPv4Address : public IPAddress {};
class IPv6Address : public IPAddress {};

int main()
{
    InterfaceIPAddress<IPv4Address> address;
    return 0;
}

此外,我尝试在编译器建议的位置添加

typename
,但所做的只是满足警告。没有解决编译错误。

c++ templates c++17 implementation enable-if
1个回答
0
投票

由于您为类添加了额外的模板参数,因此需要将其传递到实现声明中,如下所示

template<class TAddress, typename Enable>
InterfaceIPAddress<TAddress, Enable>::
InterfaceIPAddress(TAddress const &address, uint16_t flags)
    : _address(new TAddress(address)),
      _flags(flags)
{
}
© www.soinside.com 2019 - 2024. All rights reserved.