Please notice C++03 is what I really need, but for knowledge sake, I would like to see some more pretty implementations in C++11 as well.
I need a template class
template <typename T>
class A {
private:
T m_member;
public:
A(T _member);
//... MORE STUFF
void foo(T param);
};
I need:
Then I need A to look like this (exactly like above)
class A {
private:
T m_member;
public:
A(T _member);
//... MORE STUFF
void foo(T param);
};
int&
):Then I need A to look like this:
class A{
private:
T& m_member;
public:
A(T& _member);
//... MORE STUFF
void foo(T param); // still the same T, not T&
};
If I knew A received only ints, then i would be able to use specialization. But any type can be used by A's user:
main.cpp
A<int> a1;//1st version
A<int&> a2;//2nd version
A<B> a3;//1st version
A<B&> a4;//2nd version
A<C*> a5;//1st version
You can choose to specialize only some of the parameters of a class template. This is known as partial specialization. Note that function templates cannot be partially specialized; use overloading to achieve the same effect.
It is possible in C++ to get a special behavior for a particular data type. This is called template specialization. Template allows us to define generic classes and generic functions and thus provide support for generic programming.
The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.
An individual class defines how a group of objects can be constructed, while a class template defines how a group of classes can be generated. Note the distinction between the terms class template and template class: Class template. is a template used to generate template classes.
As seen (correctly) in this thread Specializing function template for reference types, the remove_reference suggested here won't work. It just won't go into the second implementation EVER, because the compiler sees T& and T just the same.
Instead you could MANUALLY tell the compiler that it is now dealing with a reference type, using the same specialization trick
template<typename T, bool isReference>
class A {
};
template<typename T>
class A<T,false>{
private:
T m_member;
public:
A(T _member);
//... MORE STUFF
void foo(T param);
}
/////////////////////////
template<typename T>
class A<T,true>{
private:
T& m_member;
public:
A(T& _member);
//... MORE STUFF
void foo(T param);
}
If you want to extract some similar behavior and avoid the code dupelication this solution causes, you could easily extract that behavior to a Base Class<T>
, and do
template<typename T,bool isReference>
class A : public BaseClass<T>{
}
and so on.
Usage would be
main.cpp
A<int,false> a1;//1st version
A<int&,true> a2;//2nd version
A<B,false> a3;//1st version
A<B&,true> a4;//2nd version
A<C*,false> a5;//1st version, as pointers are value types
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With