尝试与 typedef 交朋友时"elaborated type refers to typedef"错误



假设我有以下一段代码(一个简单的CRTP类层次结构)。我想 typedef 基类类型以节省自己的类型(在我的实际代码中,我多次使用基类类型,基类采用多个模板参数),并且我需要与基类交朋友,因为我想保持实现私有。

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 << "foon"; }
};
Derived< int > crash_dummy;

叮当 说:

[...]/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;

我该如何解决这个问题?我注意到我可以简单地为朋友类声明键入整个内容,并且它工作正常,但即使是一点点重复的代码也会让我感到有点不舒服,所以我正在寻找一个更优雅的"适当"解决方案。

我相信这在 C++03 中是不可能的,但被添加到 C++11 中,您可以在其中省略class关键字:

friend BaseType;

仅启用 C++11 并使用friend BaseType

C++03 中,不能在 typedef 上使用友元类。

友情声明中应使用详细的类型说明符 A类(101)

101) 需要详细类型说明符的类键。

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

您实际上可以在早于 C++11 的C++中执行此操作,但它需要一个相当复杂的(哈哈)解决方法,如下所示,1st 声明此"帮助程序":

template< class T > struct ParamTypeStruct { typedef T ParamType; };

然后,您的好友声明:

friend class ParamTypeStruct< BaseType >::ParamType;

最新更新