繁体   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`?

这不是最烦恼的解析:为什么不是A(()); 工作? ,它基于A a(());形式的解析A a(()); ,其OP认为可以使用额外的括号集默认构造A对象。

相比之下,我的问题是关于2个类, fg ,其中f有一个默认构造函数, g的ctor取f 我想用一个临时的f参数调用g的ctor,所有这些都不使用统一的初始化语法。 g的ctor中有一个std::cout语句,因此缺少输出表示函数声明而不是g对象实例化。 我在注释中用3个数字注释了示例代码。 #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:我认为#1声明了一个匿名函数,它返回一个g并获取一个指向一个带0参数并返回f的函数的指针。 我错了吗?

#2:所以,我认为#2中额外的括号集将强制将所包含的内容作为函数调用进行求值,即调用f的默认ctor。 但它仍然是一个功能声明。 为什么?

#3:是#2的变体,其中差异是#3添加的实例名称myG 如果#1和#2被注释掉,#3将对象实例化。 否则我在VC12中遇到这些错误:

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

fatal error LNK1120: 1 unresolved externals

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

它们意味着什么,为什么我会得到它们?

为什么#3仅在实例被命名时才是对象实例化?

如何在不命名实例或使用统一初始化的情况下获得所需的实例化效果?

第一个声明了一个名为f的函数,该函数不带参数并返回g

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

第二个是相同的,还有另一组冗余的括号(请记住,您可以根据需要使用相同功能的声明)。 但是,它们并非总是无用的。 比方说,你需要它们来声明一个返回函数指针的函数:

// 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

至于第三名:

当#1和#2在那里时,你在maing myG( ( f() ) ); f的函数声明g myG( ( f() ) ); 被解析为g类型的对象的声明,名为myG并使用函数调用的结果进行初始化。 您收到链接器错误,因为没有f的定义。

当#1和#2被注释掉时,类型f是可见的,带括号的歧义消除了:

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

没有那对,你会得到另一个函数声明。

你想要的是这个:

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

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

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM