模板模板部分专业化只使用-std = c ++ 1z与g ++ [英] Template template partial specialization only working with -std=c++1z with g++
问题描述
我发现以下代码片段:
#include >
#include< vector>
模板< typename T>
struct X:std :: false_type {};
模板< template< typename> Y类,typename U>
struct X< Y< U>> :std :: true_type {};
int main(){
if(X ())
std :: cout<< wrong\\\
; $(< std :: vector< double>>())
std :: cout<< correct\\\
;
返回0;
}
只能打印正确
当用 g ++ - 7
与 -std = c ++ 1z
编译时。其他版本的 g ++
, clang ++
或其他 std
标志失败这是一个当前实现的bug,这段代码不应该打印任何内容,或者是在C ++ 17中改变了这个代码如我所料?
这是采用 P0522 in C ++ 17,其动机来自于这个例子:
模板< template< int>类> void FI();
模板< template< auto>类> void FA();
模板< auto> struct SA {/ * ... * /};
模板< int> struct SI {/ * ... * /};
FI< SA>(); // 好;本文前的错误
FA< SI>(); //错误
模板< template< typename>类> void FD();
模板< typename,typename = int> struct SD {/ * ... * /};
FD< SD>(); // 好;本文前的错误(CWG 150)
以前, [temp.arg.template]所需的模板模板参数完全匹配。给出:
模板< template< class>班级P> X类;
模板< class T> A类;
模板< class T,class U = T> B类;
模板< class ...> C类;
X
显然是可以的,但 X
格式不正确,因为 B
需要两个模板参数(无论是否为默认值!)和由于 P
需要一个模板参数, C
C
!)
如果模板模板参数至少与参数一样特殊,新的措辞会将匹配的想法放松到更有意义的模式。这使得 X< B>
和 X< C>
都可以工作。
因此,在C ++ 17中, I have found that the following piece of code: Only prints Is this a bug of the current implementation, and this code should not print anything, or is something changed in C++17 which makes this code work as I expect? This is a result of the adoption of P0522 in C++17, whose motivation was, from the example: X
#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;
}
correct
when compiled with g++-7
with -std=c++1z
. Other versions of g++
, clang++
or other std
flags fail to produce correct.
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)
Previously, the wording in [temp.arg.template] required template template parameters to match in kind exactly. So given:
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>
is clearly okay, but X<B>
is ill-formed because B
takes two template parameters (regardless if one is defaulted!) and X<C>
is ill-formed because P
expects one template parameter and C
takes a pack (even if you could form a C
with only a single parameter!)
The new wording loosens the idea of a match to one which makes more sense - if the template template-parameter is at least as specialized as the argument. That makes X<B>
and X<C>
both work.
Hence, in C++17, X<std::vector<double>>
should pick the specialization. But before C++17, it should pick the primary. gcc is doing the right thing.
这篇关于模板模板部分专业化只使用-std = c ++ 1z与g ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!