考虑这样的模板类:
template <int opt1 = 1,
bool opt2 = false,
bool opt3 = true,
int opt4 = 50>
class X { };
我尝试只更改一个参数,但似乎C ++不能这样做。还是我错了?如何实现这样的目标:
X<opt2 = true> x;
答案 0 :(得分:2)
试试这个:
// opt1 = 1 (provided), opt2 = true (provided), opt3 = true (default), opt4 = 50 (default)
X<1, true> x;
如果要更改 second 参数的默认值,则还必须指定前一个值的值。你不能通过名字来提供参数,参数有一个名称和一个位置,事实是你根本不需要将它们命名为声明:
template <int = 1,
bool = false,
bool = true,
int = 50>
class X { };
因此,您无法为参数列表的中间中的参数定义默认值:
void f(int a, int b = 0, int c); // Error!
如果上一个函数声明合法,那么这个调用会做什么?:
f(1, 2);
它会使用f
或a = 1, b= 0, c = 2
?
a = 1, b = 2, c = unknown
答案 1 :(得分:2)
R提到的Boost版本。 Martinho Fernandes 的工作原理如下:
定义了许多选项类型(它们可以是空标记结构,或者在bool
上模板化以启用/禁用,或者其他)
template <int I> struct option_1: public std::integral_constant<int, I> {};
template <bool B> struct option_2: public std::integral_constant<bool, B> {};
template <bool B> struct option_3: public std::integral_constant<bool, B> {};
template <int I> struct option_4: public std::integral_constant<int, I> {};
定义默认值的某种类型列表(我将它与现有的模板类一起隐藏在命名空间中)
namespace impl {
typedef typelist<option_1<1>, option_2<false>,
option_3<true>, option_4<50>> X_defaults;
template <int opt1, bool opt2, bool opt3, int opt4>
class X { /* ... */ };
}
编写get
机制,从合适的类型列表中提取选项(包括一个落后于提供的默认值的版本)
完成所有这些后,您可以编写一个包装类来处理现有类的所有选项和委托,例如。
template <typename... Options>
class X: public impl::X<
get<option_1, typelist<Options...>, impl::X_defaults>::value,
get<option_2, typelist<Options...>, impl::X_defaults>::value,
get<option_3, typelist<Options...>, impl::X_defaults>::value,
get<option_4, typelist<Options...>, impl::X_defaults>::value>
{
};
您的最终调用现在看起来像:
X<option_2<true>> x;
typelist
和get
部分作为练习(以及很多错误,最有可能)留给OP,一个友好的传递编辑,或者当我有更多时间时,我。