gpt4 book ai didi

c++ - c++17类模板的参数推导中构造函数模板会不会导致歧义

转载 作者:IT老高 更新时间:2023-10-28 22:39:07 25 4
gpt4 key购买 nike

考虑一个简单的例子:

template <class T>
struct foo {
template <template <class> class TT>
foo(TT<T>&&) {}
foo(foo<T>&&){}
foo() {}
};

int main() {
foo f1(foo<int>{}); //case 1.
foo<int> f2(foo<int>{}); //case 2.
}

案例1.在clang中导致foo类的模板参数推导有歧义,而在gcc中则没有。我认为模板函数(这里 - 构造函数)在重载决议中的优先级较低。这里不是这样吗?

错误信息:

prog.cc:10:14: error: ambiguous deduction for template arguments of 'foo'
foo f1(foo<int>{}); //case 1.
^
prog.cc:4:5: note: candidate function [with T = int, TT = foo]
foo(TT<T>&&) {}
^
prog.cc:5:5: note: candidate function [with T = int]
foo(foo<T>&&){}
^
1 error generated.

[clang demo] [gcc demo]

最佳答案

这是一个 Clang 错误。候选集由 c'tors 形成的事实应该无关紧要,因为在形成候选集后,使用与隐式转换序列和模板函数排序相同的规则选择最佳重载。

引用 [over.match.funcs]/1 :

The subclauses of [over.match.funcs] describe the set of candidate functions and the argument list submitted to overload resolution in each of the seven contexts in which overload resolution is used. The source transformations and constructions defined in these subclauses are only for the purpose of describing the overload resolution process. An implementation is not required to use such transformations and constructions.

这清楚地表明重载解决过程始终相同。唯一的区别是候选集是如何形成的。

并且由 [over.match.class.deduct]/1 指定

A set of functions and function templates is formed comprising:

  • For each constructor of the primary class template designated by the template-name, if the template is defined, a function template with the following properties:

    • The template parameters are the template parameters of the class template followed by the template parameters (including default template arguments) of the constructor, if any.

    • The types of the function parameters are those of the constructor.

    • The return type is the class template specialization designated by the template-name and template arguments corresponding to the template parameters obtained from the class template.

每个 c'tor 都会在候选集中引入一个伪函数。像这样:

template <class T>                           foo(foo<T>&&) -> foo<T> 
template <class T, template<class> class TT> foo(TT<T>&&) -> foo<T>

为了进一步说明,如果这是一个自由函数bar:

template <template <class> class TT, class T>
void bar(TT<T>&&) {}

template <class T>
void bar(foo<T>&&){}

然后模板函数排序会将第一个重载置于第二个之下。

关于c++ - c++17类模板的参数推导中构造函数模板会不会导致歧义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46054228/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com