怎么会?特征中未检测到别名

时间:2018-01-09 21:18:01

标签: c++ c++11 templates variadic-templates type-alias

问题很简单:查看代码。两个静态断言都通过了。我不希望第二个通过。这是一个错误还是正常行为?

#include <array>
#include <type_traits>

template <template <class...> class Temp, class Specialization>
struct IsSpecialization : std::false_type {};

template <template <class...> class Temp, class... Ts>
struct IsSpecialization<Temp, Temp<Ts...>> : std::true_type {};

template <class...Args>
struct A {};

template <class...Args>
using AT = A<Args...>;


int main() {
    static_assert(IsSpecialization<A, A<int>>{});
    static_assert(!IsSpecialization<AT, AT<int>>{});
}

2 个答案:

答案 0 :(得分:6)

当您尝试匹配部分特化时,

_posts会被推断两次:

  • TempTemp相匹配。这通常会将AT推断为Temp
  • ATTemp<Ts...>相匹配。这会将AT<int>推断为Temp,因为A等同于AT<int>,此推论将永远不会推断别名模板(请参阅[temp.alias]/2)。

整体扣除成功 - 部分专精化是匹配 - 如果两次扣除给A<int>相同的值,即iff TempAT被认为是等效的。他们是is currently an open question

答案 1 :(得分:2)

不是解释(请参阅T.C.的答案),但解决方法是:修改IsSpecialization的真实版本,如下所示

template <template <typename...> class Temp1,
          template <typename...> class Temp2, typename... Ts>
struct IsSpecialization<Temp1, Temp2<Ts...>>
   : public std::is_same<Temp1<Ts...>, Temp2<Ts...>>
 { };

T.C。请注意,使用原始代码时,AT在被视为容器时被推断为AT,而A<Ts...>被视为类型。

诀窍是在不同的模板模板参数中推导ATA,应用相同的模板类型(Ts...)获取AT<Ts...>A<Ts...> 。但AT<Ts...>A<Ts...>属于同一类型且std::is_same了解它。