访问模板参数的受保护成员

时间:2010-07-29 16:18:24

标签: c++ templates visibility

我有一个模板类,我需要访问模板参数的受保护成员函数,如下所示:

class Foo
{
protected:
    void foo() {}
};

template<typename T>
class Bar
{
public:
    static void bar(T& self){self.foo();}
};
...
Foo f;
Bar<Foo>::bar(f);

我的问题是访问受保护的方法。我尝试将friend class T放入Bar中,但在c ++中似乎不允许这样做(编辑:无论如何都不会解决我的问题,所以看起来似乎)。我试过让Bar继承自T(template<typename T> class Bar: public T(本来可以使用私有继承,但Bar的公共接口并不是非常重要,因为类本身只是内部的)),但这不允许访问foo()也是。那么如何才能访问foo()方法?

编辑: Foo不应该知道Bar<Foo>,因为有很多Bar个类。然而,我可以对Foo进行其他更改(当然不改变公共接口)。

3 个答案:

答案 0 :(得分:5)

好吧,这是一个“腐烂在地狱”的黑客。您可以滥用这样一个事实,即您可以从派生类中形成指向受保护基础成员的成员指针。

class Foo
{
protected:
    void foo() {}
};

// Helper template to bypass protected access control
// for a member function called foo, taking no parameters
// and returning void.
template<typename T>
struct Unprotect : public T
{
    typedef void (T::*FooPtr)();
    static FooPtr GetFooPtr()
    {
        return &Unprotect::foo;
    }
};

template<typename T>
class Bar
{
public:
    static void bar(T& self){(self.*Unprotect<Foo>::GetFooPtr())();}
};

int main()
{
    Foo f;
    Bar<Foo>::bar(f);
}

答案 1 :(得分:2)

你在错误的方向做了你的朋友宣言。如果BarFoo是朋友,则表示Foo可以访问Bar的私人数据。要让Bar访问Foo的私人数据,Foo必须说Bar是其朋友。

答案 2 :(得分:0)

template<typename T>
class Bar
{
public:
    static void bar(T& self){self.foo();}
};

class Foo
{
protected:
    void foo() {}
    friend class Bar<Foo>;
};

void main()
{
    Foo f;
    Bar<Foo>::bar(f);
}