为什么 {} 作为函数参数不会导致歧义?
Why does {} as function argument not lead to ambiguity?
考虑这段代码:
#include <vector>
#include <iostream>
enum class A
{
X, Y
};
struct Test
{
Test(const std::vector<double>&, const std::vector<int>& = {}, A = A::X)
{ std::cout << "vector overload" << std::endl; }
Test(const std::vector<double>&, int, A = A::X)
{ std::cout << "int overload" << std::endl; }
};
int main()
{
std::vector<double> v;
Test t1(v);
Test t2(v, {}, A::X);
}
这会打印:
vector overload
int overload
为什么这不会由于不明确的重载解析而产生编译错误?如果删除第二个构造函数,我们会得到两次 vector overload
。 How/by 什么指标 int
比 std::vector<int>
更明确地匹配 {}
?
构造函数签名当然可以进一步修剪,但我只是被一段等效的代码欺骗了,想确保这个问题没有丢失任何重要内容。
它在[over.ics.list],强调我的
6 Otherwise, if the parameter is a non-aggregate class X and
overload resolution per [over.match.list] chooses a single best
constructor C of X to perform the initialization of an object of type
X from the argument initializer list:
If C is not an initializer-list constructor and the initializer list has a single element of type cv U, where U is X or a class derived
from X, the implicit conversion sequence has Exact Match rank if U is
X, or Conversion rank if U is derived from X.
Otherwise, the implicit conversion sequence is a user-defined conversion sequence with the second standard conversion sequence an
identity conversion.
9 Otherwise, if the parameter type is not a class:
[...]
if the initializer list has no elements, the implicit
conversion sequence is the identity conversion. [ Example:
void f(int);
f( { } ); // OK: identity conversion
end example ]
std::vector
由构造函数初始化,粗体项目符号认为它是用户定义的转换。同时,对于 int
,这是身份转换,因此它胜过第一个 c'tor 的等级。
考虑这段代码:
#include <vector>
#include <iostream>
enum class A
{
X, Y
};
struct Test
{
Test(const std::vector<double>&, const std::vector<int>& = {}, A = A::X)
{ std::cout << "vector overload" << std::endl; }
Test(const std::vector<double>&, int, A = A::X)
{ std::cout << "int overload" << std::endl; }
};
int main()
{
std::vector<double> v;
Test t1(v);
Test t2(v, {}, A::X);
}
这会打印:
vector overload
int overload
为什么这不会由于不明确的重载解析而产生编译错误?如果删除第二个构造函数,我们会得到两次 vector overload
。 How/by 什么指标 int
比 std::vector<int>
更明确地匹配 {}
?
构造函数签名当然可以进一步修剪,但我只是被一段等效的代码欺骗了,想确保这个问题没有丢失任何重要内容。
它在[over.ics.list],强调我的
6 Otherwise, if the parameter is a non-aggregate class X and overload resolution per [over.match.list] chooses a single best constructor C of X to perform the initialization of an object of type X from the argument initializer list:
If C is not an initializer-list constructor and the initializer list has a single element of type cv U, where U is X or a class derived from X, the implicit conversion sequence has Exact Match rank if U is X, or Conversion rank if U is derived from X.
Otherwise, the implicit conversion sequence is a user-defined conversion sequence with the second standard conversion sequence an identity conversion.
9 Otherwise, if the parameter type is not a class:
[...]
if the initializer list has no elements, the implicit conversion sequence is the identity conversion. [ Example:
void f(int); f( { } ); // OK: identity conversion
end example ]
std::vector
由构造函数初始化,粗体项目符号认为它是用户定义的转换。同时,对于 int
,这是身份转换,因此它胜过第一个 c'tor 的等级。