模板别名上is_same_template的奇怪行为

时间:2014-04-06 09:14:14

标签: c++ templates c++11 template-aliases

以下计划......

#include <iostream>
#include <type_traits>

template <typename T>
struct Template{};

template <typename T>
using Alias = Template<T>;

template
    <
        template <typename>
        class T1,
        template <typename>
        class T2
    >
struct is_same_template : std::false_type{};

template
    <
        template <typename>
        class T
    >
struct is_same_template<T, T> : std::true_type{};

int main() {
    std::cout << std::boolalpha;
    std::cout << "Template == Template: " << is_same_template<Template, Template>::value << std::endl;
    std::cout << "Template == Alias: " << is_same_template<Template, Alias>::value << std::endl;
    std::cout << "Alias == Alias: " << is_same_template<Alias, Alias>::value << std::endl;
}

...输出...

Template == Template: true
Template == Alias: false
Alias == Alias: true

...使用 g ++ 4.8.1 clang 3.4 vc ++ 18.00.21005.1 编译。

这些编译器中的错误还是标准的要求?

1 个答案:

答案 0 :(得分:3)

这是标准所要求的行为,它完全符合逻辑。别名模板不是模板别名(尽管有些人希望这样做)。最初,即使在标准中也存在一些混淆,请参阅http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1244

在当前的标准化表单中,别名模板就像它的非模板化计数器部分:它为一个类型别名。在模板版本中,类型可能是依赖的。

它立即被替换。例如,Alias<T> T本身就是模板参数将是依赖类型Template<T> - 从这个意义上说,名称​​别名模板可能有点令人困惑,因为它表明将在某些时候实例化别名声明。但实际上别名模式立即被替换 - 在这个意义上,模板化版本更像是依赖别名声明,它总是存在并且不需要实例化,而不是作为别名声明模板。

在这一点上,对于这些术语来说,我们的意思是什么,这有点过于哲学。