为什么具有真正价值enable_if似乎与直接放置空白的工作方式不同

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

本文关键字:空白 方式不 工作 if enable 为什么      更新时间:2023-10-16

当我尝试使用部分专用化实例化我的模板化函子时,我遇到了歧义错误。 下面的Foo和Bar是相同的,只是Fooenable_if_t被替换为Bar中的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,所以我不明白为什么他们的行为不同。

此外,如果有人可以提供资源来"简单"描述用于在可行的部分专业化(即不是规范)之间进行选择的过程,那就太棒了。

n.m. 从评论中得到的回答:

你的两个专业都不比另一个专业更专业。因此,当两者匹配时,存在歧义。OTOH 当你使用 void 时,第二个专业化与任何东西都匹配,因此第一个专业化变得严格地更加专业化。