模板模板参数和默认值 [英] Template template parameter and default values

查看:183
本文介绍了模板模板参数和默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

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,

(12):尽管是缺陷报告的解决方法,但是默认情况下,所有语言版本均禁用此功能,并且可以在Clang 4及更高版本中使用标志-frelaxed-template-template-args明确启用该功能.对标准的更改缺少模板部分排序的相应更改,从而导致合理且先前有效的代码存在歧义错误.该问题有望很快得到解决.

(12): Despite being the the resolution to a Defect Report, this feature is disabled by default in all language versions, and can be enabled explicitly with the flag -frelaxed-template-template-args in Clang 4 onwards. The change to the standard lacks a corresponding change for template partial ordering, resulting in ambiguity errors for reasonable and previously-valid code. This issue is expected to be rectified soon.

因此,您可以冒险使用标志-frelaxed-template-template-args.

So, at your risk, you can try with the flag -frelaxed-template-template-args.

这篇关于模板模板参数和默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆