根据模板参数更改属性访问权限

时间:2011-10-11 19:46:09

标签: c++ templates

我有一个基类,它是一个如下所示的模板:

template <typename T>
class Foo
{
public:
    T bar;
};

我想要做的是介绍一个模板参数,该参数可用于控制成员栏的访问模式。

这样的事情:

template <typename T,bool publicBar=true>
class Foo
{

public: 
    // If publicBar is false, insert protected: here
    T bar;
};

这可能吗?

感谢。

编辑: 许多人这么问,对于那些为什么我这样做有趣的人,这是我的真实代码!

    // Class used for automatic setter/getter generation.
template <typename T,publicSetter=true>
class Property
{
public:
    Property(){}
    Property(T value):mObject(object){}
    T operator()()const
    {
        return mObject;
    }
public: // This is where I want the protected:
    virtual void operator()(T newObject)
    {
        this->mObject = newObject;
    }
private:
    T mObject;
};

5 个答案:

答案 0 :(得分:11)

这可以使用部分模板专业化来完成:

template <typename T,bool publicBar>
class Foo
{
};

template <typename T>
class Foo<T,true>
{
public: 
    T bar;
};

template <typename T>
class Foo<T,false>
{
protected: 
    T bar;
};

这里唯一的问题是你需要为每个专业化复制整个类... UNLESS 你想在基类之上进行复制,例如:

template <typename T>
class FooBase
{
    //the goods go here
};

template <typename T,bool publicBar>
class Foo : public FooBase<T>
{
};

template <typename T>
class Foo<T,true> : public FooBase<T>
{
public: 
    T bar;
};

template <typename T>
class Foo<T,false> : public FooBase<T>
{
protected: 
    T bar;
};

答案 1 :(得分:3)

是的,这是可能的使用部分特化。是否可取是另一个问题 - 首先,这个解决方案不能扩展,因为你需要2 ^ n个特化,其中n是你控制访问的变量数。你真的希望你的类的接口根据模板参数的值来改变吗?

看起来你正在创造一些难以维护,难以理解和过于聪明的东西。

尽管如此,如果您认为这是一个好主意,请按照以下方式进行操作:

template <typename T, bool publicBar=true>
class Foo
{
public:
  T bar;
};

template <typename T>
class Foo<T,false>
{
protected:
  T bar;
};

答案 2 :(得分:2)

是的,使用显式类模板专业化:

template<bool B> class Foo;

template<> class Foo<true>
{
public: 
    int n_;
};

template<> class Foo<false>
{
protected:
    int n_;
};

int main()
{
    Foo<true> fa;
    fa.n_;
    Foo<false> fb;
    fb.n_;  // ERROR: protected
}
但是,这似乎是一个非常糟糕的主意。你为什么要这样做?

答案 3 :(得分:1)

我认为你可以通过模板专业化来做到这一点。完全未经测试的代码。

template <typename T,bool publicBar=true>
class Foo
{

public: 
    // If publicBar is false, insert protected: here
    T bar;
};

template <typename T, false>
class Foo
{

protected: 
    // If publicBar is false, insert protected: here
    T bar;
};

但是要真的考虑一下你为什么要这样做。 public数据对于封装非常危险,而protected几乎就是这样。能够利用客户端API的解决方案在长期内可能更易于维护。

答案 4 :(得分:1)

怎么样

template<typename T>
struct FooBase {
    T bar;
};

template<typename T, bool publicBar>
class Foo : public FooBase<T> {};

template<typename T>
class Foo<T, false> : protected FooBase<T> {};

通过这种方式,您不必多次定义bar,而只需定义一次。