c++ - 为什么 SFINAE 需要 'Enable' 类模板参数?

标签 c++ template-specialization sfinae class-template

(本题与C++11/C++14无关:示例使用C++03编译)

enable_bool<T>有成员(member)::type仅当 Tbool

template <class T>
struct enable_bool
{};

template <>
struct enable_bool< bool >
{ typedef bool type; };

在下一个片段中,部分特化是正确的(参见 gcc.godbolt.org )

template <class T, class U, class Enable = T>
struct Foo
{
    static int bar() { return 0; }
};

template <class T, class U>
struct Foo< T, U, typename enable_bool<T>::type >
{
    static int bar() { return 1; }
};

int main()
{
    return Foo <int, bool>::bar();
}

作为enable_bool<T>::type已经对应T (当 Tbool 时)
我们很想分解参数 TEnable .
但是编译器提示(参见 gcc.godbolt.org )

template <class T, class U>
struct Foo
{
    static int bar() { return 0; }
};

template <class T, class U> //ERROR non-deducible template parameter 'T'
struct Foo< typename enable_bool<T>::type, U >
{
    static int bar() { return 1; }
};

为什么编译器无法推导出模板参数 T在上述部分特化中?

最佳答案

最后这个问题甚至与 SFINAE 无关!

考虑这个没有 SFINAE 的非常简单的片段:
enable<T>::type始终与 T 相同无论提供什么 T类型。

template <class T>
struct enable
{ typedef T type; };       // Enable always

template <class U, class V>
struct Foo
{
    static int bar() { return 0; }
};

template <class X, class Y> //ERROR non-deducible parameter 'X'
struct Foo< typename enable<X>::type, Y >
{
    static int bar() { return 1; }
};

int main()
{
    return Foo<int, bool>::bar();
}

当编译器尝试匹配 Foo<int, bool> 时与 Foo<typename enable<X>::type,Y>

  • 1st param U = int <--> enable<X>::type => 无法推断 X
  • 2nd param V = bool <--> Y

编译器不是为推断X而设计的来自等式 int = enable<X>::type .
因此,编译器需要开发人员的一些帮助。
需要另一个参数:Enable .

下面的固定片段添加了 Enable类模板参数。
编译器执行以下匹配:

  • 1st param U =int <--> X
  • 2nd param V =bool<--> Y
  • 3rd param Enable=int <--> enable<X>::type (从第一个参数推导出X)
    (第三个参数是 int 因为声明 class Enable=U 意味着默认情况下第三个参数与第一个参数相同)

固定片段:

template <class T>
struct enable
{ typedef T type; };       // Enable always

template <class U, class V, class Enable = U>
struct Foo
{
    static int bar() { return 0; }
};

template <class X, class Y> // Compiler can deduce 'X'
struct Foo< X, Y, typename enable<X>::type >
{
    static int bar() { return 1; }
};

int main()
{
    return Foo<int, bool>::bar();
}

关于c++ - 为什么 SFINAE 需要 'Enable' 类模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32998062/

相关文章:

c++ - 使用成员作为参数调用构造函数解析为变量定义

c++ - 如何有条件地将函数添加到类模板?

c++ - 奇怪的! static const unsigned 不是类模板中的常量表达式?

c++ - 检测 CRTP 基类的 sibling

c++ - 桌面 SCADA 应用程序 - 通过 C++ 读取和写入 PLC

c++ - Qt:创建一个 QDoubleSlider

c++ - 如何在C++中创建指针数组

c++ - 如果使用默认模板,如何产生编译器错误?

c++ - 安全回调提供程序(SFINAE、std::forward 和重载解析)

c++ - 检测最终类别的特征