带有类型参数的模板模板参数?

时间:2018-06-13 14:44:13

标签: c++ template-meta-programming

以下代码无法编译。 甚至可以将Configuration<t, u>的实例作为模板参数传递? (从常量表达式的优化中获益)

API:

template <int t, bool u>
struct Configuration {
  static constexpr int commonValue = t;
  static constexpr bool debug = u;
};

template <
  template<int t, bool u> Configuration<t, u> &conf,
  int x
>
class A {
public:
  int doSomething() {
    if (conf.debug) { // Optimize away if false
      // ...
    }
    return x * conf.commonValue; // Optimize to e.g. 6 with `conf.commonValue` =
                                 // 3, `x` = 2
  }
};

API的用户应该能够:

int main() {
    static constexpr Configuration<3, false> conf;
    A<conf, 2> a;
    A<conf, 5> b;
    A<conf, 8> c;
    std::cout << a.doSomething() << std::endl; // 6 (evaluated at compile time!)
    std::cout << b.doSomething() << std::endl; // 15
    std::cout << c.doSomething() << std::endl; // 24
}

1 个答案:

答案 0 :(得分:3)

由于Configuration的属性为static,您应使用模板类型参数 1

template <class ConfT, int x>
class A {
public:
  int doSomething() {
    if (ConfT::debug) { // Optimize away if false

    }
    return x * ConfT::commonValue;
  }
};

然后:

// Alias (not required):
using conf = Configuration<3, false>;

A<conf, 2> a;
A<conf, 3> b;

如果你想要非静态成员,我不认为这在C ++之前是可行的17(没有将Configuration的模板参数传递给A),但在C ++ 17中你可以做 1

template <auto const& conf, int x>
class A {
public:
  int doSomething() {
    if (conf.debug) { // Optimize away if false
    }
    return x * conf.commonValue;
  }
};

但请注意,您只能传递具有静态存储持续时间的变量的引用。

1 在第一种情况下,您可以通过专门化Configuration<...>将类型限制为A,在第二种情况下,您可以限制conf的类型{1}}使用std::enable_if的额外模板参数。

您还应该在constexpr中制作属性Configuration,而不仅仅是const

template <int t, bool u>
struct Configuration {
  static constexpr int commonValue = t;
  static constexpr bool debug = u;
};