【问题标题】:again about C++ SFINAE in enable_if_t再次关于 enable_if_t 中的 C++ SFINAE
【发布时间】:2018-12-03 13:02:32
【问题描述】:

我试图弄清楚为什么 SFINAE 不能使用直接模板参数初始化?

它以这种形式工作,当我在这里声明另一个模板参数时:

#include <iostream>

template <bool B, class T = void>
class enable_if {};

template <class T>
struct enable_if<true, T> {    typedef T type; };

template <bool B, class T>
using enable_if_t = typename enable_if<B,T>::type;

template< typename T >
struct Y {

public:
    template< typename U = T >
    enable_if_t<true, U>
    foo() {
        return 111;
    }

    template< typename U = T >
    enable_if_t<false, U>
    foo() {
        return 222;
    }
};

int main() {
    Y< double > y;
    std::cout << y.foo() << std::endl;
}

(打印出 111)

但是如果我重构这个语法,编译器会报错:

#include <iostream>

template <bool B, class T = void>
class enable_if {};

template <class T>
struct enable_if<true, T> {
    typedef T type;
};

template <bool B, class T>
using enable_if_t = typename enable_if<B,T>::type;

template< typename T >
struct Y {    
    template< typename U = enable_if_t<true, T> >
    U
    foo() {
        return 11;
    }

    template< typename U = enable_if_t<false, T> >
    U
    foo() {
        return 12;
    }
};

int main() {
    Y< double > y;
    std::cout << y.foo() << std::endl;
}

“不能重新声明类成员”我假设第二个实例无效,应该被 SFINAE 排除?

为什么我不能像这样声明 foo():

enable_if_t<true, T> foo() { return 11; } 
enable_if_t<false, T> foo() { return 12; } 

仅基于类模板的 T 参数? 第二个 enable_if_t 应该无效,应该丢弃 foo() 的实例,对吧?

【问题讨论】:

    标签: c++ templates template-meta-programming sfinae


    【解决方案1】:

    在第二种情况下,你声明了两个类方法:

    template<typename U> U foo();
    

    你不能有两个具有相同签名和名称的模板类方法,就像你不能声明两个具有相同签名和名称的非模板类方法一样:

    int bar();
    

    int bar();
    

    您的两个模板类方法具有不同的模板参数默认值,但这无关紧要。模板参数默认值不被视为签名的一部分。 SFINAE 在这里没有发挥作用。 SFINAE 是在模板 substitution 发生时发生的事情,即“S”部分,而不是声明。

    【讨论】:

    • 但是为什么我不能简单地声明: enable_if_t foo() { return 11; } enable_if_t foo() { 返回 12; } 基于类模板的参数?第二个 enable_if_t 应该是无效的,应该丢弃 foo() 的实例,对吧?
    • 因为在执行模板替换时再次发生 SFINAE。在使用模板替换某些东西之前,您必须拥有有效的模板声明。此时,替换失败不是错误。但是你必须首先有一个有效的模板声明,然后才能开始尝试替换某些东西。而且您不能声明具有相同签名和名称的两个类方法。结束。
    • 我不明白区别.. 所以“缺席”返回类型是无效的声明,意味着编译器错误,对吧?但是一旦我得到有效的声明,为什么“template enable_if_t foo()”会进入不同的“Substitution”阶段?换句话说,你如何区分?您如何准确地告诉(从语法的角度来看)您应该编写另一个模板参数“U”并通过 enable_if 声明返回类型,这将作为替代......即我只是想弄清楚如何“从头开始”编写此类代码的心理模型
    猜你喜欢
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多