C++ C++;函数数';s参数由模板参数固定

C++ C++;函数数';s参数由模板参数固定,c++,arrays,templates,initialization,C++,Arrays,Templates,Initialization,我有这样一个模板类: template <unsigned N> class Pixel { float color[N]; } Pixel<N> (float x_1, float x_2, ..., float x_N) { color[0] = x_1; color[1] = x_2; ... } #include <vector> #include <iostream> #include <algo

我有这样一个模板类:

template <unsigned N>
class Pixel {
    float color[N];
}
Pixel<N> (float x_1, float x_2, ..., float x_N) {
    color[0] = x_1;
    color[1] = x_2;
    ...
}
#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;
}

显然,我不能为每个
N
手工实现构造函数。那么,如何通过模板元编程或任何其他技术来实现这一目标呢?

我会像这样使用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;
}
#包括
#包括
模板
类像素
{
公众:
像素(标准::数组值)
{

对于(size_t i=0;i来说,其他答案都是好的和实用的,但问题很有趣,这样做背后的技术可以为类似但更复杂和/或实用的问题和解决方案打下良好的基础。以下是一些按照您描述的方式计算构造函数参数的方法:

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::forward(浮动)…}{
静态断言(sizeof…(Floats)==N,“必须提供N个参数”);
}
私人:
浮色[N];
};
int main(){
像素p(3.4f、5.6f、8.f);
像素p2(1.2f);//静态
}

这里的很多内容取决于您从何处开始(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};
}
然而,与@Chris的解决方案不同,这并不试图强制传递给定数量的参数——它只符合存储传递的任何数量。作为回报,它更易于使用。您不需要指定大小——它可以从传递的项目数中计算出来

如果您喜欢这个总体思路,但坚持使用数组和C++03(为什么?),您可以这样做:

template <unsigned N>
class Pixel {
    float color[N];
}
Pixel<N> (float x_1, float x_2, ..., float x_N) {
    color[0] = x_1;
    color[1] = x_2;
    ...
}
#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;
}
#包括
#包括
#包括
模板
类像素{
T色[N];
公众:
像素(T和矩阵)[N]){
标准:复制n(矩阵,n,颜色);
}
};
模板
像素生成_像素(T(&矩阵)[N]){
返回像素(矩阵);
}
int main(){
浮动a[]={1.1,2.2,3.3,4.4,5.5};
像素p=制作像素(a);
返回0;
}

在这种情况下,我已经将
float
作为模板参数传递,但是如果你真的确定它总是
float
,你可以传递大小,使用
float
而不是
T
std::tuple
仍然是C++11,顺便说一句,总是有
boost::array
boost::tuple
,though、 事实上,我想做的是上面描述的,也许是更实际的事情。这至少是其他更复杂事情的一个很好的例子。回答好。回答好,但不是
std::vector
,你可以使用
std::array
@iammilind:是的,可以,但borgleader已经证明了这一点,而且没有在这种情况下,不清楚它是否一定是唯一的(甚至是最好的)选择。这也不是说这是一个坏主意,只是在不知道用法的情况下,很难说。在任何情况下,如果必须在
std::array
std::vector
之间做出选择,那么它必须是
std::array
。不仅从性能角度来看,而且从可读性角度来看,代码的读取器都是正确的确保大小永远不会改变。因为这里的大小是在编译时知道的,所以最好使用
std::array
。这就是我的想法:)@iammilind:无论如何,这不是唯一的考虑因素。举个例子,与
std::vector
相比,
std::array
的最大大小通常是非常有限的。这是。谢谢你,克里斯,你第一次让我知道了这个特性。也许我需要去学习C++11的新特性。@OliverQ,它们非常有趣,非常有用易变模板是最难理解和使用的模板之一。我通常不善于将它们正确地用于元编程目的。