4

次のようなテンプレート クラスがあります。

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。では、テンプレートのメタプログラミングやその他の手法を使用して、この目標を達成するにはどうすればよいでしょうか?

4

3 に答える 3

9

他の回答は適切で実用的ですが、質問は興味深いものであり、そのようなことを行う背後にある手法は、同様の、より複雑で実用的な問題と解決策の優れた基礎を形成できます。説明した方法でコンストラクターの引数をカウントするものを次に示します。

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
}
于 2013-07-12T03:44:43.290 に答える
2

ここでの多くは、どこから始めているか (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代わりにとして保存する場合は、実際にsdoubleを渡す必要があります。float

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常に.floatT

于 2013-07-12T04:41:28.850 に答える