问题描述
考虑以下代码:
template<typename T>
struct A { };
// same as A, but with one extra defaulted parameter
template<typename T, typename F = int>
struct B { };
template<template<typename> typename T>
T<int> build() { return {}; }
int main()
{
build<A>(); // works in gcc and clang
build<B>(); // works in gcc, does not work in clang
}
g ++(7.3.0)可以很好地编译代码,但是clang ++(5.0.1)发出以下信息:
g++ (7.3.0) compiles the code just fine, however, clang++ (5.0.1) emits the following:
example.cpp:14:5: error: no matching function for call to 'build'
build<B>(); // works in gcc, does not work in clang
^~~~~~~~
example.cpp:9:8: note: candidate template ignored: invalid
explicitly-specified argument for template parameter 'T'
T<int> build() { return {}; }
哪个编译器是正确的?
注意:重要的一行显然是:
Note:The important line is obviously:
template<template<typename> typename T>
因为两个编译器都满意:
Because both compilers are satisfied with:
template<template<typename...> typename T>
所以问题是传递模板模板参数时是否应考虑默认值.
So the question is whether default values should be considered when passing template template arguments.
推荐答案
据我所知,您的代码从C ++ 17开始是正确的,以前是错误的.
As far I know, your code is correct starting from C++17, wrong before.
根据 P0522R0 ,这是新标准的一部分,在该标准中,我看到了一个与您的代码非常非常相似的示例(请参见概述"):
This according P0522R0, that is part of new standard, where I see an example that is very, very similar to your code (see "overview"):
template <template <typename> class> void FD();
template <typename, typename = int> struct SD { /* ... */ };
FD<SD>(); // OK; error before this paper (CWG 150)
根据 ccpreference中的编译器支持表,g ++支持版本7的P0522R0,版本4的clang ++.因此,两个编译器均应支持您的代码.
According the compiler support tables in ccpreference, g++ support P0522R0 from version 7, clang++ from version 4. So both compiler should support your code.
但是在此页面中查看该表,就定义了对llvm(clang)5的支持部分",并根据注释,
But looking the table in this page, the support for llvm (clang) 5 is defined "partial" and, according a note,
因此,您可以冒险使用标志-frelaxed-template-template-args
.
So, at your risk, you can try with the flag -frelaxed-template-template-args
.
这篇关于模板模板参数和默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!