是否可以定义两个具有相同名称的不同模板(按模板参数数量)?
这就是我想要做的事情:
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;
};
}
我在第二个FunctionObject
结构定义的右括号末尾提到了太多模板参数的错误。
我知道这可以在C#中完成,但对C ++不确定。有人可以在这里说清楚吗?
答案 0 :(得分:11)
我认为部分专业化可以解决问题:
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;
};
}
您也可以从包含多个参数的主模板开始。
我认为C ++ 11它的可变参数模板允许它更加漂亮,但我没有时间玩这个,所以我最好把它留给别人展示。
答案 1 :(得分:6)
显示sbi建议的可变参数模板解决方案:
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;
};
}
现在您可以按照您喜欢的顺序添加特化,而无需修改其他模板(除非模板参数的数量/类型冲突)。
答案 2 :(得分:5)
我认为您可以使用一个类模板,为第二个模板参数提供默认类型参数:
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;
};
答案 3 :(得分:1)
我相信像这样的东西也会起作用,但是单独的课程可能不是你想要的:
namespace MyNamespace
{
class AbstractFunctionObject
{
//shared functionality here
};
template<class TRet>
class ConcreteFunctionObjectA : AbstractFunctionObject
{
typedef typename TRet ReturnType;
virtual ReturnType const operator()() const = 0;
};
template<class TRet, class TArg0>
class ConcreteFunctionObjectB : AbstractFunctionObject
{
typedef typename TRet ReturnType;
typedef typename TArg0 FirstArgumentType;
virtual ReturnType const operator()(FirstArgumentType const &arg) const = 0;
};
}