Sva*_*zen 7 c++ templates g++ clang++ c++17
我发现以下一段代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
仅correct在使用g++-7with 编译时打印-std=c++1z.其它版本g++,clang++或者其他std标志不能产生正确的.
这是当前实现的错误,并且此代码不应该打印任何内容,或者是否在C++ 17中发生了变化,这使得此代码按预期工作?
Bar*_*rry 10
这是在C++ 17中采用P0522的结果,其动机来自以下示例:
Run Code Online (Sandbox Code Playgroud)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;
Run Code Online (Sandbox Code Playgroud)
X<A>显然是可以的,但是格式X<B>不正确,因为B需要两个模板参数(无论一个是否默认!)并且格式X<C>不正确因为P需要一个模板参数并且C需要一个包(即使你只能形成一个C参数!)
如果模板模板参数至少与参数一样专用,那么新的措辞就会放松匹配的想法.这使得X<B>与X<C>双方的工作.
因此,在C++ 17中,X<std::vector<double>>应该选择专业化.但在C++ 17之前,它应该选择主要的.gcc正在做正确的事.