简体   繁体   English

最烦恼的解析:为什么不是`g((f()));`调用`f`的默认构造函数并将结果传递给带有`f`的`g`的ctor?

[英]Most vexing parse: why doesn't `g( ( f() ) );` call `f`'s default constructor and pass the result to `g`'s ctor that takes a `f`?

This isn't a duplicate of Most vexing parse: why doesn't A a(()); 这不是最烦恼的解析:为什么不是A(()); work? 工作? , which is based on a parse in the form of A a(()); ,它基于A a(());形式的解析A a(()); , whose OP thought would be able to default-construct an A object using the extra set of parentheses. ,其OP认为可以使用额外的括号集默认构造A对象。

In contrast, my question is about 2 classes, f and g , where f has a default constructor and g 's ctor takes an f . 相比之下,我的问题是关于2个类, fg ,其中f有一个默认构造函数, g的ctor取f I want to call g 's ctor with a temporary f argument, all without using uniform initialization syntax. 我想用一个临时的f参数调用g的ctor,所有这些都不使用统一的初始化语法。 There's a std::cout statement in g 's ctor, so the lack of output signifies a function declaration instead of g object instantiation. g的ctor中有一个std::cout语句,因此缺少输出表示函数声明而不是g对象实例化。 I annotated the sample code with 3 numbers in the comments. 我在注释中用3个数字注释了示例代码。 #1 and #2 were compiled with #3 commented out, and vice versa: #1和#2编译时#3注释掉了,反之亦然:

#include <iostream>
struct f {};
struct g {
    g(f) { std::cout << "g's ctor\n"; }
};
int main() {
                          // -----Output-----
    g( f() );             // #1: function declaration; expected
    g( ( f() ) );         // #2: also a function declaration; UNEXPECTED
    // g myG( ( f() ) );  // #3: "g's ctor" ONLY if #1 & #2 are commented out;
                          //     ^ ... linker error otherwise
}

#1: I thought #1 declares an anonymous function that returns a g and takes a pointer to a function that takes 0 arguments and returns an f . #1:我认为#1声明了一个匿名函数,它返回一个g并获取一个指向一个带0参数并返回f的函数的指针。 Am I wrong? 我错了吗?

#2: So, I thought the extra set of parentheses in #2 will force the enclosed contents to be evaluated as a function call, namely a call to f 's default ctor. #2:所以,我认为#2中额外的括号集将强制将所包含的内容作为函数调用进行求值,即调用f的默认ctor。 But it's still a function declaration. 但它仍然是一个功能声明。 Why? 为什么?

#3: is a variant of #2, where the difference is #3's added instance name myG . #3:是#2的变体,其中差异是#3添加的实例名称myG #3 instantiates the object if #1 and #2 are commented out. 如果#1和#2被注释掉,#3将对象实例化。 Otherwise I get these errors in VC12: 否则我在VC12中遇到这些错误:

error LNK2019: unresolved external symbol "struct g __cdecl f(void)" (?f@@YA?AUg@@XZ) referenced in function _main and error LNK2019: unresolved external symbol "struct g __cdecl f(void)" (?f@@YA?AUg@@XZ) referenced in function _main

fatal error LNK1120: 1 unresolved externals . fatal error LNK1120: 1 unresolved externals

and this error in g++ 4.8: undefined reference to 'f()' 和g ++ 4.8中的这个错误: undefined reference to 'f()'

What do they mean, and why am I getting them? 它们意味着什么,为什么我会得到它们?

Why is #3 an object instantiation only when the instance is named? 为什么#3仅在实例被命名时才是对象实例化?

How can I get the desired instantiation effect without naming the instance or using uniform initialization? 如何在不命名实例或使用统一初始化的情况下获得所需的实例化效果?

The first one declares a function called f that takes no parameters and returns g . 第一个声明了一个名为f的函数,该函数不带参数并返回g

     g( f() );
  //  ^     ^  redundant set of parentheses

The second one is the same, with yet another redundant set of parentheses (remember that you can have as many declarations of the same functions as you wish). 第二个是相同的,还有另一组冗余的括号(请记住,您可以根据需要使用相同功能的声明)。 They are not always useless, though. 但是,它们并非总是无用的。 You need them, say, to declare a function that returns a function pointer: 比方说,你需要它们来声明一个返回函数指针的函数:

// function taking an int and returning
// a pointer to a function that takes a char
// and returns a g
g ( *f(int) )(char);
//^         ^ needed, syntax error without them

As for third: 至于第三名:

When #1 and #2 are there, you've got a function declaration for f in main and g myG( ( f() ) ); 当#1和#2在那里时,你在maing myG( ( f() ) ); f的函数声明g myG( ( f() ) ); is parsed as a declaration of an object of type g , named myG and initialized with a result of a function call. 被解析为g类型的对象的声明,名为myG并使用函数调用的结果进行初始化。 You get a linker error because there's no definition for f . 您收到链接器错误,因为没有f的定义。

When #1 and #2 are commented out, the type f is visible, and the disambiguation with parentheses kicks in: 当#1和#2被注释掉时,类型f是可见的,带括号的歧义消除了:

g myG( ( f() ) )
//     ^     ^   these force an expression

Without that pair, you'd get another function declaration. 没有那对,你会得到另一个函数声明。

What you want is this: 你想要的是这个:

   ( g(f()) );
// ^        ^  must be an expression as declarations can't be parenthesized

or something less Lisp-y: static_cast<g>(f()); 或更少的东西Lisp-y: static_cast<g>(f());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 没有匹配的 function 来调用:错误:必须使用 '.*' 或 '-&gt;*' 来调用指向成员 function 在 'f (...)' 中的指针,例如 '(... -&gt;* f) (...)' - No matching function to call: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘f (…)’, e.g. ‘(… ->* f) (…)’ C ++:通用的“call-functions-f-follow-by-g”方法? - C++: Generic “call-functions-f-followed-by-g” method? 为什么B :: f不解决歧义,但A :: f呢? - Why doesn't B::f solve the ambiguity but A::f does? “(f(x))+ g(y)”能否确保在C ++中首先调用f(x)? - Does “(f(x))+g(y)” can make sure call f(x) first in C++? g++“调用”一个没有括号的函数(不是 f() 而是 f; )。 为什么它总是返回1? - g++ "calling" a function without parenthesis (not f() but f; ). Why does it always return 1? 如何使ss &lt;&lt; f像printf(“%g”,f)一样工作; - how to let ss << f work like printf(“%g”, f); printf零填充差异在%g和%f之间 - printf zero padding difference between %g and %f 在C ++中对f(g(),h())的评估顺序 - Order of evaluation of f(g(), h()) in C++ 为什么g ++的选项“-Winline”不起作用? - Why doesn't g++'s option “-Winline” work? 为什么Visual Studio的调试模式Step Into(F11)有时不进入某些功能? - Why Visual Studio's debug mode Step Into (F11) sometimes doesn't enter inside some functions?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM