簡體   English   中英

轉換依賴於std :: vector初始化列表構造函數的C ++ 11代碼

[英]Converting C++11 code that depends on std::vector initialization list constructor

由於微軟不支持使用初始化列表來構造std::vector一個很好的C ++ 11特性,遺憾的是我需要重構一些代碼以便與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);

看起來很笨拙。 也許我錯過了一個更好的解決方案?

是的,使您的構造函數成為模板,並通過引用接受數組。 它需要是一個模板,因為數組長度將是推導出的參數: template<int N> MyClass::MyClass(int (&array)[N]) { } 當你傳遞int whatever[4] ,N顯然被推斷為4。

[編輯]在C ++ 11之前,代碼片段{1,2,3,4}在數組和POD結構聲明之外沒有任何意義。 MyClass既不是,也就是說有一個合適類型的聲明是不可避免的,並使用它來在下一行初始化MyClass

你可以用一些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));
}

當然,您可以進一步定制它(例如直接為構造函數創建“variadic”重載等)。

您可以使用輔助函數來完成它,但是您必須提供長度,因此它不如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(1, 2, 3, 4) make_vec<4>({1, 2, 3, 4})這樣的宏生成make_vec<4>({1, 2, 3, 4})調用,但我傾向於遠離宏,因此該部分是離開作為練習。 另外,只需升級您的編譯器或使用另一個:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM