Suppose we have this structure:
namespace some_namespace::types {
using foo_t = int;
}
namespace some_namespace::classes {
class bar {
public:
auto do_stuff() -> types::foo_t;
};
}
using namespace some_namespace::classes;
auto bar::do_stuff() -> types::foo_t {
return 1;
}
This code compiles happily in GCC6.
On the other hand, VS15 with the /std:c++latest
switch enabled doesn't recognize the return type of do_stuff
. It returns C2653.
Now, what I find highly suspicious is that this gets fixed by changing the second half to this:
using namespace some_namespace;
auto classes::bar::do_stuff() -> types::foo_t {
return 1;
}
which in my eyes should be equal. Am I mistaken in thinking that this is a MSVC bug? What does the standard say about this?
This has nothing to do with the C++17 feature, which didn't touch using-directives, nor indeed with using-directives at all. MSVC produces the same error from
namespace some_namespace{
namespace types {
using foo_t = int;
}
namespace classes {
class bar {
public:
auto do_stuff() -> types::foo_t;
};
}
}
using some_namespace::classes::bar;
auto bar::do_stuff() -> types::foo_t {
return 1;
}
For the members of a class
X
, a name used [...] in the definition of a class member outside of the definition ofX
, following the member's declarator-id, shall be declared in one of the following ways:
before its use in the block in which it is used or in an enclosing block ([stmt.block]), or
shall be a member of class
X
or be a member of a base class ofX
([class.member.lookup]), or[...two bullet points about nested and local classes omitted...]
if
X
is a member of namespaceN
[...], before the use of the name, in namespaceN
or in one ofN
's enclosing namespaces.
Name lookup for types
should first look inside bar
, then inside classes
, then inside some_namespace
. That last one should find the namespace types
.