为什么这个程序调用operator()而不是构造函数? [英] Why does this program call operator () instead of the constructor?

查看:244
本文介绍了为什么这个程序调用operator()而不是构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是一个程序,编译没有警告例如。 GNU C ++:

  $ g ++ -ot -Wall -pedantic -Wshadow t.cpp 

$。 /t.exe
调用barney :: barney()
调用foo :: operator()()
调用barney :: barney()



但是它完全无法在MSVC ++上编译:

  $ cl / EHsc t.cpp 
Microsoft(R)32位C / C ++优化编译器版本15.00.30729.01 for 80x86
版权所有(C)Microsoft Corporation。版权所有。

t.cpp
t.cpp(17):错误C2380:'fred'(带返回类型的构造函数或当前类名的非法重定义)之前的类型b $ b t.cpp(17):error C2208:'fred':没有成员使用此类型定义

更重要的是,当它编译时,输出不是我想要的。



这是:

  #include< iostream> 

using :: std :: cerr;

struct fred;

struct foo {
inline fred operator()();
};

struct barney {
barney():v_(0){cerr< calling barney :: barney()\\\
; }
int v_;
};

struct fred:public barney {
foo fred;
int joe;
struct fred memfunc(){return fred(); }
};

inline fred foo :: operator()()
{
cerr<< 调用foo :: operator()()\\\
; return fred();
}

int main(int argc,const char * argv [])
{
fred f;
f.memfunc();
return 0;
}

它输出:

 调用barney :: barney()
调用foo :: operator()()
调用barney :: barney()

但我会期望这样:

 调用barney :: barney()
调用barney :: barney()

我得到我的输出吗?这是标准行为吗?如果是,为什么标准的哪些部分是相关的?



除了接受的答案, David Rodriguez 提供了良好的答案详细说明了在标准中我可以声明的成员名为 fred 因为在 fred

/ code>结构你有一个 fred (类型 foo )的成员, c $ c> struct fred 。当你这样做:

  return fred 

... fred 对象类型 foo 而不是 fred 结构类型,因此 foo ()的成员。


$ b < $ c> fred
结构类型。编译器必须选择一个或另一个,并且它根据C ++标准的第3.4节(名称查找)中定义的规则这样做。



fred 使用命名空间限定来引用类型:

  :fred(); 


Here is a program that compiles without warning on e.g. GNU C++:

$ g++ -o t -Wall -pedantic -Wshadow t.cpp

$ ./t.exe
Calling barney::barney()
Calling foo::operator()()
Calling barney::barney()

But it completely fails to compile on MSVC++:

$ cl /EHsc t.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

t.cpp
t.cpp(17) : error C2380: type(s) preceding 'fred' (constructor with return type, or illegal redefinition of current class-name?)
t.cpp(17) : error C2208: 'fred' : no members defined using this type

What's more, when it does compile, the output is not what I'd expect. Can someone shed some light on what would be the required standard behaviour for this code?

Here it is:

#include <iostream>

using ::std::cerr;

struct fred;

struct foo {
   inline fred operator ()();
};

struct barney {
   barney() : v_(0) { cerr << "Calling barney::barney()\n"; }
   int v_;
};

struct fred : public barney {
   foo fred;
   int joe;
   struct fred memfunc() { return fred(); }
};

inline fred foo::operator ()()
{
   cerr << "Calling foo::operator()()\n"; return fred();
}

int main(int argc, const char *argv[])
{
   fred f;
   f.memfunc();
   return 0;
}

It outputs this:

Calling barney::barney()
Calling foo::operator()()
Calling barney::barney()

But I would expect this:

Calling barney::barney()
Calling barney::barney()

Why do I get the output I do? Is this standard behavior? If it is, why, which sections of the standard are relevant?

In addition to the accepted answer, David Rodriguez gave an excellent answer detailing where it says in the standard that I'm allowed to declare the member named fred of struct fred.

解决方案

Because in the fred structure you have a member fred (of type foo) which shadows the definition of struct fred. When you then do:

return fred();

... the fred refers to the object of type foo rather than the fred struct type, and so the foo () operator is called.

Notice that the name "fred" refers to two different things - the member, of type foo, and the fred struct type. The compiler must choose one or the other, and it does so according to the rules defined in section 3.4 ("Name Lookup") of the C++ standard.

You can force fred to refer to the type using a namespace qualification:

return ::fred();

这篇关于为什么这个程序调用operator()而不是构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆