Is it possible to define two different template (by number of template arguments) classes with the same name?
Here's what I am trying to do:
namespace MyNamespace
{
template<class TRet>
class FunctionObject
{
typedef typename TRet ReturnType;
virtual ReturnType const operator()() const = 0;
};
template<class TRet, class TArg0>
class FunctionObject
{
typedef typename TRet ReturnType;
typedef typename TArg0 FirstArgumentType;
virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
};
}
I get an error mentioning too many template arguments at the end of closing bracket of the second FunctionObject
struct definition.
I know this can be done in C#, but wasn't sure about C++. Can someone please shed some light here?
I think partial specialization would do the trick:
namespace MyNamespace {
template<class TRet, class TArg0>
class FunctionObject
{
typedef typename TRet ReturnType;
typedef typename TArg0 FirstArgumentType;
virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
};
template<class TRet>
class FunctionObject<TRet,void>
{
typedef typename TRet ReturnType;
virtual ReturnType const operator()() const = 0;
};
}
You could also start with a primary template with more than one parameter.
I think C++11 its variadic templates allows this to be more nifty, but I hadn't had the time to play with this, so I'd better leave that to someone else to show.
To show sbi's suggested variadic template solution:
namespace MyNamespace {
template<typename...> FunctionObject;
template<class TRet, class TArg0>
class FunctionObject<TRet,TArg0>
{
typedef typename TRet ReturnType;
typedef typename TArg0 FirstArgumentType;
virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
};
template<class TRet>
class FunctionObject<TRet>
{
typedef typename TRet ReturnType;
virtual ReturnType const operator()() const = 0;
};
}
Now you can add specializations in whatever order you like, without modifying the other templates (unless the number/type of template parameters conflict).
I think you can make it work with one class template, providing default type argument for the second template parameter as:
struct null_type {};
template<class TRet, class TArg0 = null_type>
class FunctionObject
{
typedef typename TRet ReturnType;
typedef typename TArg0 FirstArgumentType;
//both functions here
virtual ReturnType const operator()() const = 0;
virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
};
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