约束成员模板的外定义规则是什么? [英] What are the rules for out-of-line definitions of constrained member templates?

查看:42
本文介绍了约束成员模板的外定义规则是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

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 拒绝了:

gcc accepts this, but clang rejects it with:

error: out-of-line definition of 'f' does not match any declaration in 'S<T>'

这是询问 之前,但那里没有答案.

This has been asked about before, but there is no answer there.

另一方面,如果 B 不是模板,我写这个 代码:

On the other hand, if B is not a template, and I write this 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 拒绝代码:

clang accepts this, but gcc rejects the code with:

error: no declaration matches 'void S<T>::f()'


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


So are either of these snippets valid?

推荐答案

S 的定义中,它是一个不完整的类型.并且类成员访问运算符需要一个完整的类型.

During the definition of S<X> it is an incomplete type. And the class member access operator requires a complete type.

但是你可以用下面的代码解决这个问题:

But you could solve the situation with the following code:

#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() {}

这篇关于约束成员模板的外定义规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆