I'd advise against it, as it will just make the code really hard to read. But if you really want to go ahead, you have to keep prefixing the nested class with the class
keyword. Where that's syntactically invalid, use a typedef:
class Foo
{
public:
class Lock
{
// Operations that require the lock...
};
class Lock Lock() noexcept {
typedef class Lock cLock;
return cLock();
}
};
As to the errors, clang is correct on this one. You cannot use typename
for disambiguation like this, and I don't think it's supposed to be usable outside of templates at all.
Standard references:
C++11[class.name]§4
specifies howLock
hidesclass Lock
and how it can be accessed asclass Lock
.C++11[class.name]§2
states that:If a class name is declared in a scope where a variable, function, or enumerator of the same name is also declared, then when both declarations are in scope, the class can be referred to only using an elaborated-type-specifier
An elaborated-type-specifier is the
class X
form. Note this implies thattypename Foo::Lock
is not a valid way of referring to it.