According to the standard [class]/2:
… The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name.…
Moreover, [basic.scope.pdecl]/9:
The point of declaration for an injected-class-name (Clause 9) is immediately following the opening brace of the class definition.
Finally, [basic.lookup.classref]/3 and its example:
If the unqualified-id is ~ type-name, the type-name is looked up …
struct A { };
struct B {
struct A { };
void f(::A* a);
};
void B::f(::A* a) {
a-> ~ A(); // OK: lookup in *a finds the injected-class-name
}
So far, we can gather:
If the above is correct, then why does the following code fails to compile (in MSVC2015):
struct inj
{};
typedef struct inj::inj inj2;
The error message
Error C2039 '{ctor}': is not a member of 'inj'
seems to be at odds with the standard:
Note: For example, the constructor is not an acceptable lookup result in an elaborated-type-specifier so the constructor would not be used in place of the injected-class-name. —end note
Since the following code compiles and runs correctly in other compilers, it is a bug in MSVC2015.
#include <boost/type_index.hpp>
#include <iostream>
struct inj
{
int g;
};
typedef struct inj::inj inj2;
int main()
{
inj2 ii;
std::cout << boost::typeindex::type_id_with_cvr<decltype(ii)>().pretty_name() << '\n';
}
UPDATE: Reported as bug.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With