我在c ++中使用模板元编程工作了很多,最近我尝试编写一个类型特征来比较间接模板模板和类型时遇到了一些奇怪的行为。
我试图将给定template template
参数的签名与类型相匹配,以确定该类型是否是模板的扩展。特点很简单:
template<template<typename> class Template, typename T>
struct is_template : std::false_type{};
template<template<typename> class Template, typename T>
struct is_template<Template,Template<T>> : std::true_type{};
这适用于显式类型:
template<typename T> struct Template{};
static_assert( is_template<Template,Template<int>>::value, "" );
但是只要我们使用类型别名应用任何级别的间接,它就会变得有趣。例如:
template<typename T> using type = Template<T>;
static_assert( is_template<type,type<int>>::value, "" );
将无法使用clang和icc进行编译,但无法使用gcc进行编译。
我已使用g++
(直到预发布版本7),clang++
(上行4.0 rc2)和icc
(16和17)测试了此行为;每次使用-std=c++14
进行编译。似乎g++ 4.9.0
及以上版本能够正确地编译它,而clang++
和icc
则不能。
可以看到一个实例:here。
我的问题是这个;是标准明确定义的这种模板间接级别吗?或者这是一种灰色区域和/或编译器错误,我只是不幸碰到了绊倒?我尝试在c ++ 1z的n4618
标准草案中找到答案,但找不到任何结论(尽管我可能已经错过了它)。
希望有人可以帮我解决这个问题!