【问题标题】:Specializing class with SFINAESFINAE的专业课
【发布时间】:2016-05-17 15:32:01
【问题描述】:

我想写一个template class 用 SFINAE 检查一个特征。

正如我在那篇文章中所读到的那样,类不能“重载”:template overloading and SFINAE working only with functions but not classes

我写了以下代码:

class AA { public: using TRAIT = int; };
class BB { public: using TRAIT = float; };

template < typename T, typename UNUSED = void> class X;

template < typename T>
class X<T, typename std::enable_if< std::is_same< int, typename T::TRAIT>::value, int >::type>
{
    public:
        X() { std::cout << "First" << std::endl; }
 };

template < typename T>
class X<T, typename std::enable_if< !std::is_same< int, typename T::TRAIT>::value, unsigned int >::type>
{
    public:
        X() { std::cout << "Second" << std::endl; }
};

int main()
{
    X<AA> a;
    X<BB> b;
}

但它只是失败了:

error: aggregate 'X<AA> a' has incomplete type and cannot be defined
         X<AA> a;
               ^

error: aggregate 'X<BB> b' has incomplete type and cannot be defined
         X<BB> b;

似乎没有一个模板可以工作,但我没有从编译器那里得到任何提示,为什么这两种专业化都失败了。

【问题讨论】:

    标签: c++ c++14 sfinae


    【解决方案1】:

    专业必须与主要专业相匹配。确定X&lt;AA&gt; 是什么的查找规则是首先匹配主要类型并添加默认类型,这样我们就可以找到X&lt;AA, void&gt;,然后尝试将其与所有特化进行匹配。但是您的专长都不匹配X&lt;AA, void&gt;,因此您最终获得了主要专业。主类型不是完整类型,因此会出现错误。

    为什么它们都不匹配?因为你写道:

    typename std::enable_if< std::is_same< int, typename T::TRAIT>::value, int >::type
    

    对于评估为intAA,与void 不匹配,因此不考虑专业化。你只想:

    typename std::enable_if< std::is_same< int, typename T::TRAIT>::value>::type
    

    或者真的:

    std::enable_if_t< std::is_same< int, typename T::TRAIT>::value>
    

    类似地,对于BB,第二个专业化的第二个类型计算为unsigned int 而不是void - 所以它也不匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-21
      • 2012-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多