c++ - 约束成员模板的外定义规则是什么?

标签 c++ templates language-lawyer

考虑以下 code :

template <typename T>
struct S 
{
    template <typename = void>
    static constexpr bool B = true;

    template <std::enable_if_t<S<T>::template B<>, int> = 0>
    void f();
};

template <typename T>
template <std::enable_if_t<S<T>::template B<>, int>>
void S<T>::f() {}
gcc 接受了这一点,但 clang 拒绝了它:
error: out-of-line definition of 'f' does not match any declaration in 'S<T>'
这是asked关于之前,但那里没有答案。

另一方面,如果 B不是模板,我写这个code :
template <typename T>
struct S 
{
    static constexpr bool B = true;

    template <std::enable_if_t<S<T>::B, int> = 0>
    void f();
};

template <typename T>
template <std::enable_if_t<S<T>::B, int>>
void S<T>::f() {}
clang 接受了这一点,但 gcc 拒绝了以下代码:
error: no declaration matches 'void S<T>::f()'

那么这些片段中的任何一个都有效吗?

最佳答案

期间定义S<X>它是一个不完整的类型。并且类成员访问运算符需要一个完整的类型。
但是您可以使用以下代码解决这种情况:

#include <type_traits>

template <typename T>
struct S {

    template <typename = void>
    static constexpr bool B = true;

    template <
        typename TX = T,
        std::enable_if_t<S<TX>::template B<>, int> = 0>
    void f();
};

template <typename T>
template <typename TX, std::enable_if_t<S<TX>::template B<>, int>>
void S<T>::f() {}

//-----------

template <typename T>
struct S2 {

    static constexpr bool B = true;

    template <
        typename TX = T,
        std::enable_if_t<S2<TX>::B, int> = 0>
    void f();
};

template <typename T>
template <typename TX, std::enable_if_t<S2<TX>::B, int>>
void S2<T>::f() {}

关于c++ - 约束成员模板的外定义规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63642952/

相关文章:

c++ - 列表结构和数组的奇怪问题

c++ - 如何从 DLL 导出模板?

javascript - 用户登录后 Meteor 重新渲染模板

c++ - 如何使用 C++ 在 Mac 中获取键盘布局

c++ - 是否允许 C++ 标准库实现加强 noexcept 规范?

amazon-web-services - 每个环境的不同 Cloud Formation 参数值

c++ - 移动选择的构造函数而不是复制。 [引用标准]

c - `int` 总是签名的吗?

c++ - 在模板模板参数的情况下,由 decltype(auto) 推导的引用非类型模板参数是否可转发

c++ - 修改调用另一个类函数的类中的变量