不,标准 C++ 中没有任何内容可以实现这一点。 @FlorisVelleman 在评论中指出的一种选择是引入别名模板:
template <class UnderlyingT1, class StringT = std::string>
using options_defT0 = options<int, UnderlyingT1, StringT>;
这样做的缺点是必须显式复制默认参数UnderlyingT0
在别名定义中,但至少它仅在一处重复。
许多 Boost 库都使用替代选项。他们引入了一个特殊的标签use_default
和做that默认值。像这样的事情:
struct use_default {};
template<typename UnderlyingT0 = use_default, typename UnderlyingtT1 = use_default, typename StringT = use_default>
struct options
{
using RealUnderlyingT0 = typename std::conditional<
std::is_same<UnderlyingT0, use_default>::value,
int,
UnderlyingT0
>::type;
using RealUnderlyingT1 = typename std::conditional<
std::is_same<UnderlyingT1, use_default>::value,
long,
UnderlyingT1
>::type;
using RealStringT = typename std::conditional<
std::is_same<StringT, use_default>::value,
std::string,
StringT
>::type;
};
这里的缺点是 1. 你无法通过查看模板声明来判断默认参数,2.options<>
and options<int, long, std::string>
是不同的类型。
前者可以通过良好的文档来解决,而后者可以通过明智地使用转换函数和基类来帮助。