2017-11-18 102 views
2

我有一个结构,我想初始化这样的:如何聚合 - 初始化这个结构?

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 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错误。我希望它使用一个适当的向量类聚合构造函数。我的结构应该扩展向量类 而不是我能否做到这一点声明我自己的构造函数(哪一个)?

我该如何解决这个问题?

回答

2

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

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

用这种方法你的构造函数可以捕获字面常量。

另外,由于Jarod42 noted in commentsexplicit的构造函数不能像checkPoints a = {};那样被调用。你只能把它像

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

请注意,您在这里使用了一个右值初始化,这样就不会被非const左值参考捕获。它只能由右值引用或常量左值引用捕获。

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

不管怎么说,这是声明参数为const,如果你不修改它引用一个很好的做法。

+0

随着'explicit',这将是'关卡someCheckpoints {..}'(无'=') – Jarod42

+0

并用'VECTOR'需要额外的大括号,'initializer_list'可以避免这种情况。 – Jarod42

+0

不幸的是,添加'const'并不能解决问题。关于'explicit',我可以使用'{..}'和'= {..}'。我使用它,因为单个参数构造函数应该被标记为避免无意的隐式转换。 – Kesse

0

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

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