类模板参数推导和默认模板参数 [英] Class template argument deduction and default template parameters

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

问题描述

以下精简代码不适用于最新的clang ++ 5,但已被g ++ 7接受:

The following stripped down code doesn't work with the latest clang++5 but is accepted by g++7:

template<typename Wrapped, typename U>
struct wrapper;

template<typename Wrapped, typename U=int>
struct wrapper
{
    wrapper() = default;

    // Automatic deduction guide
    constexpr explicit wrapper(Wrapped) noexcept {}
};

int main()
{
    struct {} dummy;
    constexpr auto wrapped = wrapper(dummy);
}

它失败,并显示以下错误消息:

It fails with the following error messages:

<source>:18:30: error: no viable constructor or deduction guide for deduction of template arguments of 'wrapper'
    constexpr auto wrapped = wrapper(dummy);
                             ^
<source>:12:24: note: candidate template ignored: couldn't infer template argument 'U'
    constexpr explicit wrapper(Wrapped) noexcept {}
                       ^
<source>:4:8: note: candidate template ignored: could not match 'wrapper<Wrapped, U>' against '(anonymous struct at <source>:17:5)'
struct wrapper;
       ^
<source>:9:5: note: candidate function template not viable: requires 0 arguments, but 1 was provided
    wrapper() = default;
    ^

但是,如果我将默认模板参数=int从类模板定义移至正向声明,则一切工作正常(U被按预期推导为int),就好像只有默认模板参数在创建推导指南使用的虚构函数模板集时,要考虑到前向声明.

However if I move the default template parameter =int from the class template definition to the forward declaration, everything works perfectly (U being deduced to int as expected), as if only the default template parameter in the forward declaration was taken into account when create the set of fictional function templates used by deduction guides.

我尝试阅读标准措辞,但在这种情况下无法从中得到很多帮助.生成虚构函数模板时,仅将前向声明中的默认模板参数用作预期的行为,还是编译器错误?

I tried to read the standard wording but couldn't get much out of it for this specific case. Is only taking the default template parameter in the forward declaration the intended behaviour when generating the fictional function templates, or is this a compiler bug?

推荐答案

这不是对标准本身的引用 1 ,但我有足够的信心将其视为答案.

This is not a quote of the Standard per se1, but I feel confident enough to consider it an answer.

根据cppreference,在 默认模板参数:

According to cppreference, on Default template arguments:

出现在声明和定义中的默认模板参数与默认函数参数的合并方式相似:

Default template arguments that appear in the declarations and the definition are merged similarly to default function arguments:

template<typename T1, typename T2 = int> class A;
template<typename T1 = int, typename T2> class A;
// the above is the same as the following:
template<typename T1 = int, typename T2 = int> class A;

但是在同一范围内不能两次为同一参数提供默认参数

But the same parameter cannot be given default arguments twice in the same scope

template<typename T = int> class X;
template<typename T = int> class X {}; // error

这暗示着一条隐含规则:可以在模板声明或模板定义中为模板类型参数提供默认类型.

This implies an implicit rule: A template type argument can be given a default type in the template declaration or template definition interchangeably.

clang ++ 5表现出的行为肯定是一个错误.

The behavior clang++5 exhibits is definitly a bug.

1)由用户Oliv提供:

1) Provided by user Oliv:

[temp.param]/10

可以使用的默认 template-arguments 集合是通过以默认函数参数([dcl.fct.default])相同的方式合并模板的所有先前声明中的默认参数而获得的. [示例:

[temp.param]/10

The set of default template-arguments available for use is obtained by merging the default arguments from all prior declarations of the template in the same way default function arguments are ([dcl.fct.default]). [ Example:

template<class T1, class T2 = int> class A;
template<class T1 = int, class T2> class A;

等同于

template<class T1 = int, class T2 = int> class A;

-示例]

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

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