I'm trying to write an templated class with some methods/operators etc.. Now when the class is of an specififc type i would like to have extra append methods specially suited for that type which arent there for any other type. I dont' want to copy all the code into an new class.
Example:
template<typename T>
class Buffer
{
Buffer(const Buffer<Type> &Buffer) : mData(Buffer.mData)
{
}
Buffer<Type> Clone()
{
}
void Append (T * aData)
{
}
// this one should only be there when Type is an unsigned char
void Append (wchar_t * aData)
{
}
}
is this at all possible?
Greetz, Richard.
Directly this is impossible. Full specialization is full specialization which means you must implement the specialized class from scratch. However I can suggest the following trick:
template<class T>
class CommonFunctionality
{
//your methods here
};
template<class T>
class MyClass: public CommonFunctionality<T>
{
};
template<>
class MyClass<MyType>:public CommonFunctionality<MyType>
{
public:
//your extra method here
};
thanks to Mark's suggestion, here's what you can do with the clone method:
template<class T, class ActualType>
class CommonFunctionality
{
//your methods here
ActualType Clone(){...}
};
template<class T>
class MyClass: public CommonFunctionality<T, MyClass<T> >
{
};
template<>
class MyClass<MyType>:public CommonFunctionality<MyType, MyClass<MyType> >
{
public:
//your extra method here
};
Use a policy class to manage the interaction with the type, then your class doesn't really have to worry about the type that is passed in, an appropriate policy (and specialization of said policy) can contain all the logic specific to that type.
#include <iostream>
#include <vector>
template <typename T, typename U>
struct append_policy
{
template <typename BufferType>
static void append(BufferType& buffer, U type)
{
std::cout << "default: append U" << std::endl;
}
};
template <typename U>
struct append_policy<std::string, U>
{
template <typename BufferType>
static void append(BufferType& buffer, U type)
{
std::cout << "string: append U" << std::endl;
}
};
template <>
struct append_policy<std::string, char>
{
template <typename BufferType>
static void append(BufferType& buffer, char type)
{
std::cout << "string: append char" << std::endl;
}
};
template <typename T>
struct foo
{
template <typename U>
void append(U a)
{
append_policy<T, U>::append(buffer, a);
}
std::vector<char> buffer;
};
int main(void)
{
foo<std::string> f;
std::string test("test");
f.append(test);
f.append('C');
foo<int> f1;
f1.append(0);
return 0;
}
EDIT: now allows you to append any type to any type of MyClass
, and allows you to override specific combination of types, and potentially throw exceptions in other combinations which you don't want to support.
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