pimpl成语和模板类朋友

时间:2009-10-16 17:59:37

标签: c++ templates friend pimpl-idiom

我正在尝试使用pimpl成语来隐藏一些蹩脚的模板代码,但我不能给body类的派生类访问句柄类。我从MSVC 9 sp1收到错误C2248。这是一些复制错误的代码:

//
// interface.hpp
//
namespace internal{
    template<class T>
    class specific_body;
}

class interface
{
    struct body;
    body *pbody_;
    interface(body *pbody);

    template<class T>
    friend class internal::specific_body;

public:

    ~interface();

    interface(const interface &rhs);

    bool test() const;

    static interface create( bool value );
};

//
// interface.cpp
//
struct interface::body
{
    virtual ~body(){}

    virtual bool test() const = 0;

    virtual interface::body *clone() const = 0;
};

class true_struct {};
class false_struct {};

namespace internal {

template< class T>
class specific_body : public interface::body
{ // C2248
public:

    specific_body(){}

    virtual bool test() const;

    virtual interface::body *clone() const
    {
        return new specific_body();
    }
};

bool specific_body<true_struct>::test() const
{
    return true;
}

bool specific_body<false_struct>::test() const
{
    return false;
}

} //namespace internal

interface::interface(body *pbody) : pbody_(pbody) {}

interface::interface(const interface &rhs) : pbody_(rhs.pbody_->clone()) {}

interface::~interface() { delete pbody_; }

bool interface::test() const
{
    return pbody_->test();
}

interface interface::create(bool value )
{
    if ( value )
    {
        return interface(new internal::specific_body<true_struct>());
    }
    else
    {
        return interface(new internal::specific_body<false_struct>());
    }
}

//
// main.cpp
//
// #include "interface.hpp"
//

int _tmain(int argc, _TCHAR* argv[])
{
    interface object( interface::create(true));

    if ( object.test() )
    {
        // blah
    }
    else
    {
    }
    return 0;
}

如果从我的问题中看不出来,我正在尝试隐藏interface::body和[{1}}用户的specific_bodyinterface实施内容。

5 个答案:

答案 0 :(得分:1)

您需要添加模板&lt;&gt;在模板测试方法的显式实例化中

template<> // add this line
bool specific_body<true_struct>::test() const
{
    return true;
}

答案 1 :(得分:0)

您没有限定specific_body。尝试

template<class T>
friend class internal::specific_body;

作为你的朋友声明。

答案 2 :(得分:0)

尝试使用typename吗?我想我在Sutter中读到,typename可以在未知范围内进入类,而类不会。

答案 3 :(得分:0)

除了Troubadour提到的不合格的specific_body之外,你对special_body&lt;&gt; :: test for true_struct和false_struct的专门化尝试似乎不正确。你必须专注全班。

要解决这个问题,我只需在公共部分声明 body 即可。另外,声明specific_body成为interface :: body的朋友也无济于事。

答案 4 :(得分:0)

嗯,通过在界面中使body公开声明,我能够“解决”这个问题。这解决了specific_body声明期间的C2248错误。我还让body成为interface类的朋友,并为body结构添加了一个方法:

static interface create( body *pbody )
{
    return interface(pbody);
}

如果specific_body

的实例之间存在嵌套关系,interface可以创建specific_body