2

考虑这样的模板类:

template <int opt1 = 1,
          bool opt2 = false,
          bool opt3 = true,
          int opt4 = 50>
class X  { };

我尝试只更改一个参数,但似乎 C++ 无法做到这一点。还是我错了?如何实现这样的目标:

X<opt2 = true> x;
4

2 回答 2

2

试试这个:

// 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);

它会fa = 1, b= 0, c = 2or调用a = 1, b = 2, c = unknown

于 2012-11-22T14:51:49.860 回答
2

R. Martinho Fernandes提到的 Boost 版本的工作原理如下:

  1. 定义许多选项类型(它们可以是空标签结构,或模板化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>  {};
    
  2. 定义某种类型的默认值类型列表(我会将它与现有模板类一起隐藏在命名空间中)

    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 { /* ... */ };
    }
    
  3. 编写一种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.

于 2012-11-22T16:09:36.280 回答