Let's say I have the following piece of code (a simple CRTP class hierarchy). I want to typedef the base class type to save myself typing (in my actual code, I use the base class type more than once and the base class takes several template parameters), and I need to befriend the base class since I want to keep the implementation private.
template< class D >
class Base
{
public:
void foo() { *static_cast< D * >(this)->foo_i(); }
};
template< class T >
class Derived : public Base< Derived< T > >
{
public:
typedef class Base< Derived< T > > BaseType;
private:
// This here is the offending line
friend class BaseType;
void foo_i() { std::cout << "foo\n"; }
};
Derived< int > crash_dummy;
clang says:
[...]/main.cpp:38:22: error: elaborated type refers to a typedef
friend class BaseType;
^
[...]/main.cpp:33:44: note: declared here
typedef class Base< Derived< T > > BaseType;
How do I fix this? I noticed that I could simply type out the whole thing just for the friend class declaration and it works fine, but even a tiny bit of duplicated code makes me feel a tad uncomfortable, so I'm looking for a more elegant "proper" solution.
I believe that this is not possible with C++03, but was added to C++11 in which you can simply omit the class
keyword:
friend BaseType;
Enable C++11 only and use friend BaseType
You cannot use friend class on typedef in C++03.
An elaborated-type-specifier shall be used in a friend declaration for a class(101)
101) The class-key of the elaborated-type-specifier is required.
elaborated-type-specifier:
class-key ::opt nested-name-specifieropt identifier
class-key ::opt nested-name-specifieropt templateopt template-id
enum ::opt nested-name-specifieropt identifier
typename ::opt nested-name-specifier identifier
typename ::opt nested-name-specifier templateopt template-id
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