I found myself with a nested class and a member function which had the same name. The member function is intended to return an instance of the nested class:
class Foo
{
public:
class Lock
{
// Operations that require the lock...
};
Lock Lock() noexcept {return Lock;}
};
This understandably did not work so I was looking for a way around it and tried:
return typename Foo::Lock();
This worked fine on g++ 4.7 and 4.8 but when run on clang++ 3.4 I get errors:
Without c++11: error: typename specifier refers to non-type member 'Lock' in 'Foo'
With c++11: 'error: typename specifier refers to non-type member 'Lock' in 'Foo'
This leads to my questions:
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 how Lock
hides class Lock
and how it can be accessed as class 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 that typename Foo::Lock
is not a valid way of referring to it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.