3

由于微软不支持使用初始化列表来构造的一个不错的 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

你可以通过一些Boost.Preprocessor hacking 来做到这一点:

#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 回答
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 回答