模板模板部分专业化仅适用于 -std=c++1z 和 g++
Template template partial specialization only working with -std=c++1z with g++
我发现了下面这段代码:
#include <iostream>
#include <vector>
template <typename T>
struct X : std::false_type {};
template <template <typename> class Y, typename U>
struct X<Y<U>> : std::true_type {};
int main() {
if (X<int>())
std::cout << "wrong\n";
if (X<std::vector<double>>())
std::cout << "correct\n";
return 0;
}
仅在使用 g++-7
和 -std=c++1z
编译时打印 correct
。 g++
、clang++
或其他 std
标志的其他版本无法生成正确的。
这是当前实现的错误吗,这段代码不应打印任何内容,或者是 C++17 中的某些更改使这段代码按我预期的方式工作?
这是在 C++17 中采用 P0522 的结果,其动机来自示例:
template <template <int> class> void FI();
template <template <auto> class> void FA();
template <auto> struct SA { /* ... */ };
template <int> struct SI { /* ... */ };
FI<SA>(); // OK; error before this paper
FA<SI>(); // error
template <template <typename> class> void FD();
template <typename, typename = int> struct SD { /* ... */ };
FD<SD>(); // OK; error before this paper (CWG 150)
以前,[temp.arg.template]中的措辞要求模板模板参数与实物完全匹配。所以给出:
template <template <class > class P> class X;
template <class T> class A;
template <class T, class U=T> class B;
template <class... > class C;
X<A>
显然没问题,但是 X<B>
格式错误,因为 B
有两个模板参数(不管是否有一个是默认的!)而 X<C>
是错误的-形成是因为 P
需要一个模板参数,而 C
需要一个包(即使你可以只用一个参数形成一个 C
!)
新措辞放宽了匹配到更有意义的想法 - 如果模板模板参数至少与参数一样专业。这使得 X<B>
和 X<C>
都有效。
因此,在 C++17 中,X<std::vector<double>>
应该选择专业化。但在 C++17 之前,它应该选择主要的。 gcc 正在做正确的事。
我发现了下面这段代码:
#include <iostream>
#include <vector>
template <typename T>
struct X : std::false_type {};
template <template <typename> class Y, typename U>
struct X<Y<U>> : std::true_type {};
int main() {
if (X<int>())
std::cout << "wrong\n";
if (X<std::vector<double>>())
std::cout << "correct\n";
return 0;
}
仅在使用 g++-7
和 -std=c++1z
编译时打印 correct
。 g++
、clang++
或其他 std
标志的其他版本无法生成正确的。
这是当前实现的错误吗,这段代码不应打印任何内容,或者是 C++17 中的某些更改使这段代码按我预期的方式工作?
这是在 C++17 中采用 P0522 的结果,其动机来自示例:
template <template <int> class> void FI(); template <template <auto> class> void FA(); template <auto> struct SA { /* ... */ }; template <int> struct SI { /* ... */ }; FI<SA>(); // OK; error before this paper FA<SI>(); // error template <template <typename> class> void FD(); template <typename, typename = int> struct SD { /* ... */ }; FD<SD>(); // OK; error before this paper (CWG 150)
以前,[temp.arg.template]中的措辞要求模板模板参数与实物完全匹配。所以给出:
template <template <class > class P> class X;
template <class T> class A;
template <class T, class U=T> class B;
template <class... > class C;
X<A>
显然没问题,但是 X<B>
格式错误,因为 B
有两个模板参数(不管是否有一个是默认的!)而 X<C>
是错误的-形成是因为 P
需要一个模板参数,而 C
需要一个包(即使你可以只用一个参数形成一个 C
!)
新措辞放宽了匹配到更有意义的想法 - 如果模板模板参数至少与参数一样专业。这使得 X<B>
和 X<C>
都有效。
因此,在 C++17 中,X<std::vector<double>>
应该选择专业化。但在 C++17 之前,它应该选择主要的。 gcc 正在做正确的事。