Olve Maudal 的 C++ 测验(别名模板)
Explanation behind C++ Quiz by Olve Maudal (alias template)
以下代码来自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”。来自朋友的 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.
上面的意思是Y
和Z
是不同的template-name,所以是不同的模板。 you/the 编译器可能会混淆的是 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" );
}
以上适用于 Clang,但不适用于 GCC。
编辑:正如@T.C 指出的那样。有一个活跃的 CWG issue 1286 这表明 Clang 正在按照标准当前所说的进行操作,而不是按照预期进行操作。
以下代码来自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”。来自朋友的 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.
上面的意思是Y
和Z
是不同的template-name,所以是不同的模板。 you/the 编译器可能会混淆的是 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" );
}
以上适用于 Clang,但不适用于 GCC。
编辑:正如@T.C 指出的那样。有一个活跃的 CWG issue 1286 这表明 Clang 正在按照标准当前所说的进行操作,而不是按照预期进行操作。