c++ - Olve Maudal 的 C++ 测验背后的解释(别名模板)

标签 c++ templates gcc clang alias

以下代码来自http://www.pvv.org/~oma/PubQuiz_ACCU_Apr2014.pdf (#6,第 34 页的解决方案)。目标是猜测以下内容的输出。

#include <iostream>
template <template <typename> class>
struct X {
    X() { std::cout << "1"; }
};

template<typename >
struct Y {};

template<typename T>
using Z = Y<T>;

template<>
struct X<Y> {
    X() { std::cout << "2"; }
};

int main() {
    X<Y> x1;
    X<Z> x2;
}

答案可以在第34页找到。我不明白第二种情况有别名模板,为什么X<Z>选择主模板?而不是完全特化。

正确答案应该是演示文稿中所写的“21”。我的 MinGW (gcc 5.1) 打印“22”和 http://ideone.com (使用 gcc 4.9.2)也打印“22”。来自 friend 的 MacOS X 上的 Clang 打印“21”。所以我猜这是 gcc 中的一个错误。

任何人都可以向我解释为什么 X<Z> 打印“1”吗?标准 gcc 中的哪一段可能无法实现或尚未实现?

最佳答案

我觉得是

14.5.7 Alias templates

1 A template-declaration in which the declaration is an alias-declaration (Clause 7) declares the identifier to be a alias template. An alias template is a name for a family of types. The name of the alias template is a template-name.

上面的意思是YZ是不同的template-name,所以它们是不同的模板。可能会让您/编译器感到困惑的是 Y<T>Z<T>将始终产生相同的类型。

考虑:

#include <type_traits>

template <typename>
struct W {};

template <template <typename> class>
struct X {};

template<typename>
struct Y {};

template<typename T>
using Z = Y<T>;

int main()
{
    static_assert( std::is_same< Y<int>, Z<int> >::value, "Oops" );
    static_assert( std::is_same< W<Y<int>>, W<Z<int>> >::value, "Oops" );
    static_assert( ! std::is_same< X<Y>, X<Z> >::value, "Oops" );
}

Live example

以上适用于 Clang,但不适用于 GCC。

编辑:正如@T.C 所指出的。有一个活跃的CWG issue 1286这表明 Clang 正在按照标准当前所说的进行操作,而不是按预期进行操作。

关于c++ - Olve Maudal 的 C++ 测验背后的解释(别名模板),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30242897/

相关文章:

c++ - 组合或替换多个相似的重载

django - 使用 "escape"标记作为 Django 中的良好安全模式真的是强制性的吗?

c - 加速大型开关和 if-else

C++ 覆盖嵌套类只能部分说服编译器

c++ - 在 MSVC 中使用数据成员指针作为模板参数

c++ - 在 C++ 的 while 循环中使用 pow() 函数

c++ - 为什么必须在哪里放置 “template”和 “typename”关键字?

c++ - 在扩展派生自的模板之前访问模板的基类

c++ - 有没有地方可以下载 libgomp.spec?

cocoa - .so 运行时可链接库作为插件; cocoa 能力?