Change access to properties based on template argument

I have a base class that looks like this:

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

What I would like to do is introduce a template argument that can be used to control the access mode of the toolbar.

Something like that:

 template <typename T,bool publicBar=true> class Foo { public: // If publicBar is false, insert protected: here T bar; }; 

Is it possible?

Thanks.

Edit: Many have asked, for those interested in why I am doing this, here is 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; }; 
+7
source share
5 answers

This can be done using a partial specialization of templates:

 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 thing you got is that you will need to replicate the entire class for each specialization ... UNLESS you would like to make it on top of the base class, for example:

 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; }; 
+11
source

Yes, this is possible through partial specialization. Is this another question recommended? To begin with, this solution does not scale, since you need 2 ^ n specializations, where n is the number of variables that you control access to. And do you really want to change the interface of your class based on the value of the template parameter?

It seems that you are creating something difficult to maintain, which is hard to understand and overly smart.

However, if you decide that this is a good idea, here is how you do it:

 template <typename T, bool publicBar=true> class Foo { public: T bar; }; template <typename T> class Foo<T,false> { protected: T bar; }; 
+3
source

Yes, using the special specification of the class template:

 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 } 

This seems like a really bad idea. Why do you need this?

+2
source

I think you could do it with a specialized template. Completely untested code.

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

But really think about why you want to do this. public data is really dangerous for encapsulation, and protected is almost like that. A solution that can use the client API is likely to be more serviceable in the long run.

+1
source

What about

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

Thus, you do not need to define bar several times, but only once.

+1
source

All Articles