在 C++ 中是否可以通过模板值来专门化可变数量的参数?

问题描述 投票:0回答:1

假设我有以下模板类:

template<int R> class dummy{
    public:
        // functions
    private:
        int arr[R];
};

是否可以创建一个构造函数,它接受恰好 R 个用于初始化

array
的参数?

像这样使用的东西:

dummy<3> a(1,2,3); // where array[0] is set to 1, array[1] is set to 2, and so on...

我知道如何达到相同的结果:

template<int R> class dummy{
    public:
        dummy(const int(&list)[R]){
            for (int i = 0; i < R; i++) arr[i] = list[i];
        }
    private:
        int arr[R];
};

然后使用它:

dummy<3> a({1,2,3});    // OK
dummy<3> b({1,2});      // also OK but arr[2] will be set to 0
dummy<3> c({1,2,3,4});  // compile-time error

问题是我想要编译时保证传递的列表恰好是 R 的大小,而不是更大,不是更小。如果列表较大,上述代码的编译器会抱怨,但如果较小,则不会。

我看到了这个answer,但其中的大小是由函数调用自动确定的,并且硬编码值 3 是断言的一部分。我无法使用 static_assert,因为 R 将始终是类初始化设置的值(例如,

dummy<3>
设置
R=3
,并且如果列表小于 3,构造函数调用将用 0 填充列表)。

如何保证编译时传递的参数个数正好是R?

c++ templates initializer-list
1个回答
0
投票

如果将构造函数参数化,则

static_assert()
会很好地工作。工作示例:https://godbolt.org/z/dcP683cdh

#include <cstddef>

template <int R>
class dummy {
 public:
  template <size_t N>
  explicit dummy(const int (&list)[N]) {
    static_assert(N == R);
    for (int i = 0; i < R; i++)
      arr[i] = list[i];
  }

 private:
  int arr[R];
};

dummy<3> a({1, 2, 3});
dummy<3> b({1, 2});
dummy<3> c({1, 2, 3, 4});

int main() {}
© www.soinside.com 2019 - 2024. All rights reserved.