C++模板参数固定的函数参数数量
C++ number of function's parameters fixed by template parameter
我有一个这样的模板类:
template <unsigned N>
class Pixel {
float color[N];
}
我希望有一个具有精确N
参数的构造函数来初始化类中的数组,如下所示:
Pixel<N> (float x_1, float x_2, ..., float x_N) {
color[0] = x_1;
color[1] = x_2;
...
}
显然,我不能为每个N
手工实现构造函数。那么,我如何通过模板元编程或任何其他技术来实现这个目标呢?
其他答案都很好,很实用,但问题很有趣,这样做背后的技巧可以为类似但更复杂和/或更实用的问题和解决方案奠定良好的基础。以下是按照您描述的方式计算构造函数参数的内容:
template <unsigned int N>
class Pixel {
public:
template<typename... Floats> //can't use float... anyway
Pixel(Floats&&... floats) : color{std::forward<Floats>(floats)...} {
static_assert(sizeof...(Floats) == N, "You must provide N arguments.");
}
private:
float color[N];
};
int main() {
Pixel<3> p(3.4f, 5.6f, 8.f);
Pixel<3> p2(1.2f); //static_assert fired
}
我会像这样使用std::array:
#include <array>
#include <iostream>
template<unsigned int N>
class Pixel
{
public:
Pixel(std::array<float, N> values)
{
for(size_t i=0; i<N; i++)
{
colors[i] = values[i];
}
}
private:
float colors[N];
};
int main(int argc, char* argv[])
{
std::array<float, 5> array = { 0.0f, 1.1f, 2.2f, 3.3f, 4.4f };
Pixel<5> p(array);
return 0;
}
我使用了浮动颜色[N];作为成员变量,因为这似乎就是你所拥有的,但如果由我决定,我只会存储数组本身。如果您没有访问c++11编译器的权限,那么可能有一种方法可以使用boost::tuple获得类似的结果(chris告诉我std::tuble也是c++11,oops)。
这里的很多内容取决于你从哪里开始(C++03与C++11)以及你真正想去的地方(只传递数字,或者传递std::array
之类的东西是否适合你)。
如果你有C++11,你只想传递数字,那么最简单的方法可能是:
#include <vector>
#include <iostream>
#include <initializer_list>
class pixel {
std::vector<double> color;
public:
pixel(std::initializer_list<double> && l) : color(l) {}
~pixel() {
// show the data we received:
for (double const &f : color)
std::cout << f << "t";
}
};
int main() {
pixel{1.9, 2.8, 3.7, 4.6, 5.5};
}
请注意,std::initializer_list
不支持缩小转换范围,因此如果您想将数字存储为float
而不是double
,则需要实际通过float
s:
pixel{1.9f, 2.8f, 3.7f, 4.6f, 5.5f};
然而,与@Chris的解决方案不同,这并没有试图强制传递给定数量的参数——它只是符合存储您传递的任何数字。作为回报,它更容易使用。你不需要指定大小——它会根据你传递的物品数量来计算
如果你喜欢这个总体想法,但坚持使用数组和C++03(为什么?),你可以这样做:
#include <vector>
#include <iostream>
#include <algorithm>
template<class T, size_t N>
class pixel {
T color[N];
public:
pixel(T(&matrix)[N]) {
std::copy_n(matrix, N, color);
}
};
template <class T, size_t N>
pixel<T, N> make_pixel(T(&matrix)[N]) {
return pixel<T, N>(matrix);
}
int main() {
float a [] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
pixel<float, 5> p = make_pixel(a);
return 0;
}
在这种情况下,我已经传递了float
作为模板参数,但如果你真的确定它总是float
,你可以传递大小,并使用float
而不是T
。
- 将可变参数函数的参数封装在类实例中
- QML 使用带有参数C++函数
- 使用可变参数函数作为模板参数
- 如何在C++中伪造虚拟可变参数函数模板?
- 为什么可变参数函数不适用于模板
- C++ std::functional 中的可变参数函数模板
- 可变参数函数指针的定义对于VxWorks spyLib来说不清楚
- 使用可变参数函数覆盖具有不同函数签名的虚函数
- 考虑引用和常量的可变参数函数包装器
- 使用可变参数函数将整数和/或整数数组放入单个 int 数组中
- 在可变参数函数中转发特定范围的参数
- 通过引用传递参数;函数返回类型是否必须为 VOID?
- 使用带有一个参数函数的递归找到数字的平方
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 多个可变参数函数的单个模板参数包?
- 参数数据类型未知的可变参数函数
- 可变参数函数参数包扩展
- 使用模板可变参数函数将多个参数传递给另一个函数
- 对可变参数函数的递归调用的链接器错误
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类