Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么不是';不要叫‘A(c)’总的来说,这是不明确的吗?_C++_Initialization_Language Lawyer_Ambiguous_C++17 - Fatal编程技术网

C++ 为什么不是';不要叫‘A(c)’总的来说,这是不明确的吗?

C++ 为什么不是';不要叫‘A(c)’总的来说,这是不明确的吗?,c++,initialization,language-lawyer,ambiguous,c++17,C++,Initialization,Language Lawyer,Ambiguous,C++17,为什么调用A(c)不明确 struct C; struct A { A() { std::cout << "default ctor A" << '\n'; } A(const A&) { std::cout << "copy A" << '\n'; } A(C&) { std::cout << "ctor A(C)" << '\n'; }; }; struct C {

为什么调用
A(c)main()中的code>不明确

struct C;

struct A {

    A() { std::cout << "default ctor A" << '\n'; }
    A(const A&) { std::cout << "copy A" << '\n'; }
    A(C&) { std::cout << "ctor A(C)" << '\n'; };
};
struct C {

    C() { std::cout << "default ctor C" << '\n'; }
    operator A() { std::cout << "C::operator A()" << '\n'; return A(); };
};


int main()
{
     C c;
     A a(c); 
}
如果我们注释掉构造函数A::A(C&),代码将打印:

default ctor C
C::operator A()
default ctor A
copy A
copy A

如果有这种情况,重载解析过程的目标是确定如何将
C
转换为
A
,那么它确实是不明确的,因为可以使用转换构造函数或转换函数:

void f(A);
f(c);
但是,这与以下情况不同:

A a(c);
这里,重载解析用于确定调用
A
的哪个构造函数,因此它选择参数类型与参数类型完全匹配的构造函数

C++14中的标准引用是[over.match.ctor]/1:

类类型的对象直接初始化(8.5)或从相同或 作为派生类类型(8.5),重载解析选择构造函数。对于直接初始化,候选 函数是被初始化对象类的所有构造函数。对于复制初始化 候选函数是该类的所有转换构造函数(12.3.1)。参数列表是 初始值设定项的表达式列表或赋值表达式


为什么要“模棱两可”?所谓的歧义在哪里?它是基于操作的优先级。@WakeupBrazil其中一个直接调用构造函数,另一个首先调用转换运算符,然后调用构造函数。一个操作优先于两个操作,这一点并不奇怪。通过逻辑将
char
传递到
void func(int);void func(char)也应该是不明确的。一个是“精确匹配”,另一个是“转换”。前者是严格意义上更好的重载,但声明中的表达式
a(c)
不一样,也不是
a
@WakeupBrazil类型的派生类:你在说什么
A
有一个构造函数,它将
C
作为参数。而
C
与表达式
C
@nicolabolas的类型相同,我的印象是,[over.match.ctor]/1中来自相同或派生类类型(8.5)
表达式的句子
将适用于两种情况,直接初始化和复制初始化。这就解释了我上面的评论。但现在,更仔细地看一下引用的段落,我可以看到所提及的句子只适用于复制初始化。@Nicolas,但我仍然不明白这段话如何解释
A::A(C&)
C::operator A()
没有歧义。@WakeupBrazil:“候选函数是被初始化对象类的所有构造函数”
C::operator A()
不是
A
的构造函数之一,因此它不是候选函数集的一部分。因此不存在歧义。
A a(c);