在C ++ 98中初始化结构数组的优雅方法

时间:2018-01-22 15:37:42

标签: c++ initialization c++98

我使用的是gcc版本4.9.2 如果我使用编译器标志-std = c ++ 0x进行编译,则以下代码编译正常。

#include <iostream>
#include <vector>

using namespace std;
typedef struct
{
    vector<int> a;
    int b;
} MYTYPE;

int main(void)
{
    MYTYPE test[]=
    {
        { {1,2,3},4},
        { {5,6},7},
        { {},8}
    };
}

如果删除-std = c ++ 0x标志,编译器会报告:

  

错误:无法将'{1,2,3}'从''转换为'std :: vector'

初始化test []的优雅方法是什么?

3 个答案:

答案 0 :(得分:4)

除了通过在struct中编写一组可怕的构造函数来在调用站点实现某些优雅外,没有特别优雅的方法来初始化这些struct s前C的数组++ 11

正是这些结构才开发出C ++ 11语法。

答案 1 :(得分:2)

使用C ++ 98,最好的可能是辅助功能的定义和使用:

struct Data
{
    std::vector<int> vector;
    int scalar;
};

template<std::size_t N>
Data make_data(const int (&vector)[N], int scalar)
{
    Data result;
    result.vector.assign(vector, vector+N);
    result.scalar = scalar;
    return result;
}

int main()
{
    const int vector[] = {1,2,3}; // just to annoy people using namespace std :)
    Data d = make_data(vector, 4);
    std::cout << d.vector[2] << "\n" << d.scalar << "\n";
}

live demo

答案 2 :(得分:0)

您可以从Boost.Assign复制解决方案。

类似下面的代码 - 但我们可能会认为它很优雅“只有做过一次,多次使用。

目标:

MYTYPE mm[] = {
    { VectorBuilder<int>(1)(2)(3), 4},
    { VectorBuilder<int>(3)(4)(5), 4}
};

解决方案(working example):

template <typename T>
class VectorBuilder
{
public:
    VectorBuilder(T val) : val(val), prev(0), next(0), first(this)
    {}

    VectorBuilder operator ()(T val) const
    {
        return VectorBuilder(val, this);
    }

    operator std::vector<T>() const
    {
        std::vector<T> vv;
        vv.reserve(this->getSize());
        this->build(vv);
        return vv;
    }

private:

    T val;
    const VectorBuilder* prev;
    mutable const VectorBuilder* next;
    const VectorBuilder* first;

    VectorBuilder(T val, const VectorBuilder* prev) 
      : val(val), prev(prev), next(0), first(prev->first)
    {
        prev->next = this;
    }

    std::size_t getSize() const
    {
        // TODO - see working example link
    }

    void build(std::vector<T>& vv) const
    {
        // TODO - see working example link
    }

};