Question

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:

  • Which of these is correct?
  • Is there a way to reference the nested class in the member function as in the example?
Was it helpful?

Solution

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();
    }
};

Live example

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top