加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 取决于std :: enable_if的不明确的部分特化

发布时间:2020-12-16 07:20:38 所属栏目:百科 来源:网络整理
导读:我有以下代码: #include iostreamtemplate class T,typename U = void class A;template class Tclass C{public: typedef T Var_t;};template class Tclass B : public CT{};template class Tclass ABT{public: A() { std::cout "Here." std::endl; }};temp
我有以下代码:

#include <iostream>

template <class T,typename U = void> class A;

template <class T>
class C
{
public:
    typedef T Var_t;
};

template <class T>
class B : public C<T>
{
};

template <class T>
class A<B<T>>
{
public:
    A() { std::cout << "Here." << std::endl; }
};

template <class T>
class A<T,typename std::enable_if<
                             std::is_base_of<C<typename T::Var_t>,T>::value>
                             ::type>
{
public:
    A() { std::cout << "There." << std::endl;}
};

int main() 
{
    A<B<int>> a;
    return 0;
}

当编译器尝试使用参数B< int>,std :: is_base_of< C< int>,B< int>> :: value实例化第二部分特化时,因此std :: enable_if< .. .> :: type返回void(默认类型,如果未指定).这导致“模糊的部分特化”错误,因为编译器无法在第一和第二部分特化之间做出决定.到现在为止还挺好.但是,当我将std :: enable_if中的代码替换为true时(即,第二个部分特化只是模板<类T>类A< T,typename std :: enable_if< true> :: type>),代码编译并运行.它输出“Here”,表示选择了第一个专业化.

我的问题是:如果他们最终都评估为void,为什么std :: enable_if< true> :: type的行为与std :: enable_if< std :: is_base_of< ...> ::的行为不同值GT; ::类型?

此行为已在Ideone here上经过测试和验证.

解决方法

在std :: enable_if< true> :: type情况下,您的代码定义了A类的两个特化,即:

> A< B< B< T>,void>
> A< T,std :: enable_if< true> :: type>.

这两个专业是彼此截然不同的.第一个专业化狭隘地集中在类型B< T>上.而第二种专业化更适合任何类型.此外,在第二个特化中,std :: enable_if表达式不以任何方式依赖于T.

对于任何声明A< X>一个;类型X将匹配B< something>或不.如果它匹配B< something>然后将使用第一个专业化,因为它“更专业化”.如果X不匹配B< something>然后将使用第二个更一般的专业化.无论哪种方式,你都不会得到模棱两可的错误.

有关更多详细信息,请参阅partial template specialization中有关部分排序的讨论

现在让我们考虑std :: enable_if< std :: is_base_of< ...> :: value> :: type case.

你仍然有两个专业,但第二个专业化现在以enable_if为条件,而enable_if又取决于参数T.

> A< B< B< T>,std :: enable_if< ...>>.

类型B< int>现在匹配两个特化(在某种程度上相同).显然它匹配A< B>>,void>专业化,但它也匹配A< T,std :: enable_if ...>>专业化,因为B< int>是一种满足std :: enable_if表达式强加的条件的类型.

这为您提供了两个同样有效的特化,它们是您声明变量a的候选者,因此您会得到“模糊的部分特化”错误.

如果你向main添加两个声明,这可能有助于使所有这些更具体

A<C<int>> x;
A<int>    y;

在std :: enable_if< true>中这将编译,两个声明将调用“那里”构造函数.

在更复杂的情况下,x的声明将编译并调用“there”构造函数,但y的声明将得到编译器错误.

没有int :: Var_t,因此std :: enable_if表达式将导致替换失败,SFINAE将隐藏该专门化.这意味着没有任何适合int的专业化,你将得到错误聚合’A< int> y’类型不完整,无法定义

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读