Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change property access based on template argument

Tags:

c++

templates

I have a base class that is a template that looks like this:

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

What I'd like to do is introduce a template argument that can be used to control the access mode of the member bar.

Something like this:

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

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

Is this possible?

Thanks.

Edit: Many asked so, for those interesting in why I'm doing this, here's my real code!

    // 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;
};
like image 756
monoceres Avatar asked Oct 11 '11 19:10

monoceres


2 Answers

This can be done using partial template specialization:

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;
};

The only gotcha here is that you would need to replicate the entire class for each specialization... UNLESS you wanted to make it on top of a base class, e.g.:

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;
};
like image 98
Nate Avatar answered Nov 26 '22 06:11

Nate


Yes, this is possible using partial specialization. Whether it's advisable is a another question - for a start, this solution doesn't scale as you need 2^n specializations where n is the number of variables you're controlling the access of. And do you really want the interface of your class to change based on the value of a template parameter?

It seems like you're creating something difficult to maintain, difficult to understand and overly clever.

Nevertheless, if you decide this is a good idea, here's how you would do it:

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

template <typename T>
class Foo<T,false>
{
protected:
  T bar;
};
like image 41
JoeG Avatar answered Nov 26 '22 05:11

JoeG