考虑这样的模板类:
template <int opt1 = 1,
bool opt2 = false,
bool opt3 = true,
int opt4 = 50>
class X { };
我尝试只更改一个参数,但似乎 C++ 无法做到这一点。还是我错了?如何实现这样的目标:
X<opt2 = true> x;
考虑这样的模板类:
template <int opt1 = 1,
bool opt2 = false,
bool opt3 = true,
int opt4 = 50>
class X { };
我尝试只更改一个参数,但似乎 C++ 无法做到这一点。还是我错了?如何实现这样的目标:
X<opt2 = true> x;
试试这个:
// opt1 = 1 (provided), opt2 = true (provided), opt3 = true (default), opt4 = 50 (default)
X<1, true> x;
如果你想改变第二个参数的默认值,你也必须指定前一个参数的值。您不能通过名称引用参数,参数有名称和位置,事实是您根本不需要在声明中命名它们:
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
or调用a = 1, b = 2, c = unknown
?
R. Martinho Fernandes提到的 Boost 版本的工作原理如下:
定义许多选项类型(它们可以是空标签结构,或模板化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;
The typelist
and get
parts are left as an exercise (along with lots of errors, most likely) for the OP, a kindly passing editor, or me when I have more time.