Oli*_*ker 0 c++ templates syntactic-sugar
我遇到一种情况,我需要传递可变数量的整数(在编译时已知)。
我需要实现这样的目标:
template <unsigned N>
void myFunc(std::array<int, N> values)
{
// Do something useful with the values
}
Run Code Online (Sandbox Code Playgroud)
我希望上面的代码能够工作,并且可以像这样方便地调用,而无需创建临时对象;
myFunc<4>({1, 2, 3, 4});
这实际上确实有效,但问题是这也有效......
myFunc<4>({1, 2});
这当然会使其中两个值未初始化,而我和用户都不知道。
我相信这会起作用:
template <unsigned N>
void myFunc(std::vector<int> values)
{
assert(values.size() == N);
// Do something useful with the values
}
Run Code Online (Sandbox Code Playgroud)
myFunc<4>({1, 2}); // Goes bang
myFunc<4>({1, 2, 3, 4}); // OK
Run Code Online (Sandbox Code Playgroud)
不幸的是,我无法在我的环境中分配内存),所以我必须在堆栈上执行所有操作(并且不能只接受我可以检查其大小的向量)。
我认为自己有两个选择。
std::array<int, 4> arr{ 0, 1};很好;未指定的元素只是零初始化。如果您不希望它起作用,那么这std::array不是适合您使用的正确类(或者更准确地说:您不能让它施加所需的限制)。
您当然可以创建一个可变参数模板并根据您的要求限制参数:
template<size_t N, std::convertible_to<int>...Args>
requires (sizeof...(Args) == N)
void f(Args&&...args)
{
std::array<int, N> values{args...};
for (auto e : values)
{
std::cout << e << '\n';
}
}
...
f<4>(1, 2, 3, 4);
Run Code Online (Sandbox Code Playgroud)
为什么要多次指定元素数量?只需使用 C++17 的功能进行 CTAD 并根据参数类型推导函数的模板参数即可:
template<size_t N>
void f2(std::array<int, N> const& values)
{
for (auto e : values)
{
std::cout << e << '\n';
}
}
...
f2(std::array{ 1, 2, 3, 4 });
Run Code Online (Sandbox Code Playgroud)
或者通过简单地使用 as 函数参数来避免使用模板的必要性std::initializer_list<int>:
void f3(std::initializer_list<int> values)
{
for (auto e : values)
{
std::cout << e << '\n';
}
}
...
f3({ 1, 2, 3, 4 });
Run Code Online (Sandbox Code Playgroud)