模板模板参数会导致Clang下的编译器错误,但不会导致GCC [英] Template template argument causes compiler error under Clang but not GCC
问题描述
在帮助解决模板过多中指出的问题时模板模板参数中的参数在我脑海中浮现出一个问题:在这种情况下,哪个编译器最适合该编译:
While helping with problem noted in too many template parameters in template template argument a question arose in my head: which compiler is right about the compilation in this case:
template <template <typename, typename> class Op>
class Function
{
};
template <typename A, typename B, bool is_f = std::is_floating_point<A>::value || std::is_floating_point<B>::value > struct Operator;
template <typename A, typename B>
struct Operator<A, B, false>
{};
template <typename A, typename B>
struct Operator<A, B, true>
{};
using FunctionOperator = Function<Operator>;
int main(int argc, char * argv[]){
std::cout << "hi!\n";
return 0;
}
GCC 7+可以毫无错误地进行编译. Clang 6及更高版本给出错误,表明作为模板参数传递的Operator
模板存在问题:
GCC 7+ compiles it with no errors. Clang 6 and later gives errors showing that there is a problem with Operator
template passed as template argument:
tmp.cpp:19:35: error: template argument has different template parameters than its corresponding template parameter
using FunctionOperator = Function<Operator>;
^
tmp.cpp:8:1: note: too many template parameters in template template argument
template <typename A, typename B, bool is_f = std::is_floating_point<A>::value || std::is_floating_point<B>::value > struct Operator;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tmp.cpp:3:11: note: previous template template parameter is here
template <template <typename, typename> class Op>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
很明显,即使提供了默认的第三个参数,它也将其视为3参数模板.所以这是一个问题,哪个编译器正确?标准对此有什么说法吗?
Obviously, it treats it as 3-arguments template even though the default third argument is supplied. So here is the question, which of the compilers is right? Does standard say anything about such situations?
PS我不需要解决这些问题的方法,因为它非常简单.我只想知道谁是对的"
PS I do not need a workaround for these kinds of problems as it is pretty simple. I just want to know "who is right"
推荐答案
Gcc是正确的. Clang似乎不符合C ++ 17.
Gcc is correct. Clang seems not in accordance with C++17.
从C ++ 17开始( CWG 150 ),默认的模板参数允许用于模板模板参数用更少的模板参数来匹配模板模板参数.
Since C++17 (CWG 150), the default template arguments are allowed for a template template argument to match a template template parameter with fewer template parameters.
template<class T> class A { /* ... */ };
template<class T, class U = T> class B { /* ... */ };
template <class ...Types> class C { /* ... */ };
template<template<class> class P> class X { /* ... */ };
X<A> xa; // OK
X<B> xb; // OK in C++17 after CWG 150
// Error earlier: not an exact match
X<C> xc; // OK in C++17 after CWG 150
// Error earlier: not an exact match
Operator
具有3个模板参数,第3个具有默认值,因此即使它仅需要两个模板参数,也可以将其用作模板模板参数Op
的参数.
Operator
has 3 template parameters, the 3rd one has default value, then it could be used as the argument for template template parameter Op
, even it only expects two template parameters.
这篇关于模板模板参数会导致Clang下的编译器错误,但不会导致GCC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!