为什么 enable_if with true value 似乎与直接输入 void 不同?

Why does enable_if with true value seem to work differently than putting void in directly?

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

#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,所以我不明白为什么它们的行为不同。

此外,如果任何人都可以提供 "easy" 用于 select 在可行的部分专业化(即不是规范)之间的过程的描述的资源,那就太棒了。

n.m.评论中的回答:

你们两个专业都不比另一个更专业。因此,当两者匹配时,就会出现歧义。 OTOH 当你使用 void 时,第二个专业化匹配任何东西,所以第一个变得更加专业化。