【发布时间】:2018-07-31 07:50:41
【问题描述】:
考虑以下程序:
template<template<typename ...> class>
struct foo {};
template<template<typename> class C>
struct foo<C> {};
int main() {}
Clang 以错误方式拒绝它:
类模板部分特化不特化任何模板参数
即使在最新的 clang 7.0 HEAD 中,请参阅演示 here。但是,gcc accepts it。
请参阅[temp.class.spec],其中说明了部分专业化的规则,我找不到任何禁止该模板的部分专业化的内容。尤其是特化确实是more specialized,错误信息看起来不对。
编辑:
但是gcc的行为也是异常的,考虑下面的程序:
#include <iostream>
template<template<typename ...> class>
struct foo { void show() { std::cout << "Primary.\n"; } };
template<template<typename> class C>
struct foo<C> { void show() { std::cout << "Specialized.\n"; } };
template<class...> struct bar {};
int main() {
foo<bar> f;
f.show();
}
原来gcc在这种情况下使用了专门的版本,见here。
现在我想问:
标准允许这种部分特化吗?
哪个编译器是正确的? (一个/全部/没有?)
【问题讨论】:
-
如果这种特化是有效的,那么
foo<bar>与template<typename...> struct bar {};的实例化是不明确的,不是吗? -
@NikitaKniazev 对我来说,这不是模棱两可的,它应该是主要的
foo被使用。但它似乎更复杂,请参阅 gcc here 的奇怪行为。它无条件使用专用版本... -
关于您的 ecample
foo<bar> f; f.show()... 如果您编译 C++17,请注意打印“specialized”,如果您编译 C++14,请注意打印“primary”; C++17 中关于模板-模板匹配发生了一些变化(但我并不是说 g++ 是对的……我真的非常困惑)。 -
@Walter clang 5.0 和 clang 7.0 HEAD。现场演示存在问题。
-
@max66 我不知道如何解释......但我认为如果它的格式不正确,应该在标准中的某个地方说明它......我找不到任何东西。
标签: c++ templates clang language-lawyer template-specialization