3

Microsoft は、初期化リストを使用して構成する C++11 の優れた機能をサポートしないためstd::vector、残念ながら、VS コンパイラで使用するために一部のコードをリファクタリングする必要があります。

私が考えることができる最善の方法は、配列ポインターと長さコンストラクターを使用することですvector。以前はこれを行っていました:

MyClass(std::initializer_list<T> init):myStdVector(init){

これにより、次のような素晴らしいことができました。

MyClass hi({1,2,3,4});

私が適切だと思った可変数のアイテムで。

配列を直接渡すことで、どうすれば同じエレガンスを実現できますか? 関数パラメータ内で実際に配列を初期化することは可能ですか?

私はこれを行うことができます:

MyClass(T*initArray,int arraySize):myStdVector(initArray,initArray+arraySize){

しかし、私はこれをしなければなりません:

 int whatever[4]={1,2,3,4};
 MyClass hi(whatever,4);

不格好なようです。おそらく、より良い解決策がありませんか?

4

3 に答える 3

1

はい、コンストラクターをテンプレートにして、参照によって配列を受け入れます。配列の長さは推定パラメーターになるため、テンプレートである必要があります: template<int N> MyClass::MyClass(int (&array)[N]) { }. を渡すint whatever[4]と、N は明らかに 4 と推定されます。

[編集] C++11 より前では、スニペット{1,2,3,4}は配列と POD 構造体の宣言の外では意味がありません。MyClassどちらでもないため、適切な型を宣言し、それを使用しMyClassて次の行で初期化することは避けられません。

于 2013-10-09T07:26:29.083 に答える
0

ヘルパー関数でそれを行うこともできますが、長さを指定する必要があるため、initializer_listバージョンほど良くありません。別のヘルパー ( make_vec2) も追加しました。コンパイラがそのバージョンをサポートしている場合は、配列の長さを手動で指定する必要がないため、それを使用してください。

#include <iostream>
#include <vector>

struct MyClass {
    std::vector<int> v;

    MyClass(std::vector<int> values) : v(values) {
    }
};

template <std::size_t N>
std::vector<int>
make_vec(const int (&values)[N]) {
    return std::vector<int>(values, values + N);
}

template <int... vs>
std::vector<int>
make_vec2() {
    int tmp[] = { vs... };
    return std::vector<int>(tmp, tmp + sizeof...(vs));
}

int main() {
    MyClass mc(make_vec<4>({1, 2, 3, 4}));
    MyClass mc2(make_vec2<1, 2, 3, 4>());
    std::cout << mc.v.size() << "\n";
    std::cout << mc2.v.size() << "\n";
    return 0;
}

編集: おそらく のmake_vec<4>({1, 2, 3, 4})ようなマクロを使用して呼び出しを生成できますがMAKE_VEC(1, 2, 3, 4)、私はマクロを避ける傾向があるため、その部分は演習として残します。また、コンパイラをアップグレードするか、別のものを使用してください:)

于 2013-10-09T07:56:11.443 に答える
0

Boost.Preprocessorハッキングでそれを行うことができます:

#include <boost/preprocessor.hpp>

#define BOOST_PP_LOCAL_LIMITS /*mind the space here!*/ (1, 10)  //where 10 is the max. number of arguments you can pass

// This macro will be expanded with maN ranging from 1 to 10 (as specified above)
#define BOOST_PP_LOCAL_MACRO(maN) \
  template <class T> \
  std::array<T, maN> make_array(BOOST_PP_ENUM_PARAMS(maN, T arg)) { \
    std::array<T, maN> arr; \
    BOOST_PP_REPEAT(maN, ASSIGN_ONE, %%) \
    return arr; \
  }

// BOOST_PP_REPEAT will expand this with maIdx randing from 0 to its first argument - 1 (maN-1 in your case)
#define ASSIGN_ONE(maZ, maIdx, maData) \-
  arr[maIdx] = BOOST_PP_CAT(arg, maIdx);


// Performs the actual expansion
#include BOOST_PP_LOCAL_ITERATE()


// Usage:
template <size_t N>
MyClass(std::array<T, N> arr) : myStdVector(begin(arr), end(arr)) {}

int main() {
  MyClass(make_array(1, 2, 3));
}

もちろん、それをさらに調整することもできます (コンストラクターの「可変個の」オーバーロードを直接作成するなど)。

于 2013-10-09T07:44:02.180 に答える