here program 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 fails compile on msvc++:
$ cl /ehsc t.cpp microsoft (r) 32-bit c/c++ optimizing compiler version 15.00.30729.01 80x86 copyright (c) microsoft corporation. rights reserved. t.cpp t.cpp(17) : error c2380: type(s) preceding 'fred' (constructor return type, or illegal redefinition of current class-name?) t.cpp(17) : error c2208: 'fred' : no members defined using type
what's more, when compile, output not i'd expect. can shed light on required standard behaviour code?
here 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 expect this:
calling barney::barney() calling barney::barney()
why output do? standard behavior? if is, why, sections of standard relevant?
in addition accepted answer, david rodriguez gave excellent answer detailing says in standard i'm allowed declare member named fred
of struct fred
.
because in fred
structure have member fred
(of type foo
) shadows definition of struct fred
. when do:
return fred();
... fred
refers object of type foo
rather fred
struct type, , foo
() operator called.
notice name "fred" refers 2 different things - member, of type foo, , fred
struct type. compiler must choose 1 or other, , according rules defined in section 3.4 ("name lookup") of c++ standard.
you can force fred
refer type using namespace qualification:
return ::fred();
Comments
Post a Comment