如何聚合初始化这个结构?

时间:2017-11-18 01:14:43

标签: c++ c++11 vector struct

我有一个我想要初始化的结构:

checkPoints someCheckpoints = {
    {
        mPosition(10, 18),
        mPosition(15, 20),
    },
    {
        mPosition(45, 80),
        mPosition(95, 105),
    }
};

基本上是使用聚合器初始化位置向量的向量。

这没有问题:

std::vector<PosVec> someCheckpoints = {
    {
        mPosition(10, 18),
        mPosition(15, 20),
    },
    {
        mPosition(45, 80),
        mPosition(95, 105),
    }
};

但是我需要使用struct来添加一些额外的功能。

我的代码:

struct mPosition {
    mPosition(int32_t x, int32_t y) : x(x), y(y) {}

    int32_t x;
    int32_t y;
};

typedef std::vector<mPosition> PosVec;

struct checkPoints {
    explicit checkPoints(std::vector<PosVec>& checkPoints) {
        checkPointsVec = checkPoints;
    };

    const PosVec& getRandom() const {
        return checkPointsVec[getRandomInt(0, checkPointsVec.size())];
    }

    std::vector<PosVec> checkPointsVec;
};

checkPoints someCheckpoints = { // no matching constructor
    {
        mPosition(10, 18),
        mPosition(15, 20),
    },
    {
        mPosition(45, 80),
        mPosition(95, 105),
    }
};

这会产生no matching constructor错误。我希望它使用适当的矢量类聚合构造函数。我的struct应该扩展vector类吗? 相反或者我能否这样做声明我自己的构造函数(哪一个)?

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

std::vector不是由大括号表示的。在初始化中使用时,您正在使用std::initializer_listconst正在发挥作用。所以我想写一下

explicit checkPoints(const std::initializer_list<PosVec>& checkPoints)
                     ^~~~~      ^~~~~~~~~~~~~~~~

通过这种方式,构造函数可以捕获文字常量。

此外,作为Jarod42 noted in comments,无法像explicit那样调用checkPoints a = {};构造函数。你只能称之为

checkPoints a { /* stuff */ };
checkPoints a ( /* stuff */ };

请注意,您在此处使用了右值初始化,因此不会被非const左值引用捕获。它只能由右值引用或const左值引用捕获。

checkPoints someCheckpoints = {
    {
        mPosition(10, 18),
        mPosition(15, 20),
    },
    {
        mPosition(45, 80),
        mPosition(95, 105),
    }
}; // This is an rvalue!

无论如何,如果你不修改参数,那么将参数声明为const是一个好习惯。

答案 1 :(得分:0)

构造函数需要std::vector<PosVec>作为输入参数,如下所示:

     checkPoints someCheckpoints{ 
        std::vector<PosVec>{
        {
            mPosition{10, 18},
            mPosition{15, 20},
        },
        {
            mPosition{45, 80},
            mPosition{95, 105},
        }
        }
    };