c++ - `std::enable_if<std::is_compound<double>::value>` 出现意外的 SFINAE 行为

标签 c++ c++11

我有一个模板类,我想根据模板参数启用不同的构造函数。具体来说,我想使用 std::is_compound作为标准。

SSCCE

// bla.cpp
#include <type_traits>
#include <vector>

template <typename T>
class Foo{
    double bar;
public:
    template<typename U=T, 
        class = typename std::enable_if<std::is_compound<U>::value>::type
        >
    Foo(typename T::value_type& b):bar(b){}

    template<typename U=T, 
        class = typename std::enable_if<!std::is_compound<U>::value>::type
        >
    Foo(T b):bar(b){}   
};

int main(){
    double d=1.0;
    Foo<std::vector<double>> f2(d); // works
    Foo<double> f1(d);          // compiler error
}

我收到以下编译错误:

g++ -std=gnu++11 bla.cpp

bla.cpp: In instantiation of ‘class
Foo<double>’: bla.cpp:22:18:   required from here bla.cpp:11:2: error:
‘double’ is not a class, struct, or union type

coliru

问题似乎是正在使用构造函数的第一个版本,该版本失败,因为 double::value_type不存在。问题是该构造函数不应该位于 Foo<double> 中首先,因为std::is_compound<double>::valuefalse

为什么std::enable_if好像工作不正常?

最佳答案

typename T::value_type&中,T不能被double替代。由于 T 是类模板的模板参数,而不是构造函数模板的模板参数,因此您无法通过替换失败排除重载。 SFINAE 仅在涉及相关模板的参数时才起作用。

如果您使用 typename U::value_type&,则会出现替换失败,但这不是错误,因为 U 是构造函数模板的参数,而不是类的参数模板。

关于c++ - `std::enable_if<std::is_compound<double>::value>` 出现意外的 SFINAE 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18868647/

相关文章:

c++ - 如何向 kdevelop 添加 -fpermissive 选项?

c++ - 如何将 C++ 类转换为内部类型

c++ - 子类中的编辑函数

C++ 模板类型定义

c++ - 带有构造函数的类的匿名 union/结构

c++ - 将 S3TC/DXTn 数据转换为 QImage

C++ 优化数组从 int 到 float 的转换

c++模板特化参数重复

c++ - 对二叉搜索树进行单元测试

c++ - map vs unordered_map 几个元素