为什么带有true值的enable_if似乎与直接使用void有所不同?

时间:2016-02-28 05:45:31

标签: c++ sfinae

当我尝试使用部分特化实例化模板化仿函数时,我遇到了歧义错误。下面的Foo和Bar是相同的,除了Foo的{​​{1}}被enable_if_t中的void替换为Bar

#include <iostream>
#include <vector>

using namespace std;

template<class T, class Enable = void>
  struct Foo;

template<class T>
struct Foo<T, enable_if_t<!std::is_pointer<T>::value>>{
    void operator()(){
    }
};


template<class T, class...Rest>
struct Foo<std::vector<T, Rest...>>
{
    void operator()(){
      cout<<"In vector"<<endl;
    }
};

template<class T, class Enable = void>
  struct Bar;

template<class T>
struct Bar<T, void>{
    void operator()(){
    }
};


template<class T, class...Rest>
struct Bar<std::vector<T, Rest...>>
{
    void operator()(){
      cout<<"In vector"<<endl;
    }
};



int main()
{
   // Foo<vector<int>> f; // <== this fails with the error below:
    Bar<vector<int>> b;
}

如果退回注释掉的行,我会得到以下内容

prog.cc:46:22: error: ambiguous partial specializations of 'Foo<std::__1::vector<int, std::__1::allocator<int> >, void>'
    Foo<vector<int>> f;
                     ^
prog.cc:10:8: note: partial specialization matches [with T = std::__1::vector<int, std::__1::allocator<int> >]
struct Foo<T, enable_if_t<!std::is_pointer<T>::value>>{
       ^
prog.cc:17:8: note: partial specialization matches [with T = int, Rest = <std::__1::allocator<int>>]
struct Foo<std::vector<T, Rest...>>

有人可以解释一下发生了什么吗?我认为enable_if_t<SOME_TRUE_VALUE>的类型是void,所以我不明白为什么表现不同。

此外,如果任何人都可以为用于在可行的部分特化(即不是规范)之间进行选择的过程的“简单”描述提供资源,那将是非常棒的。

1 个答案:

答案 0 :(得分:1)

n.m.的评论回答:

你的专业都没有比另一个更专业。因此,当两者匹配时,存在歧义。 OTOH当你使用void时,第二个专门化根本就匹配任何东西,所以第一个专门化变得更加专业化。

相关问题