初始化reference_wrapper数组

时间:2018-04-15 05:10:20

标签: c++ reference-wrapper

从C到C ++,我正在努力了解智能指针的世界。引用。我有以下内容:

class Game {
public:
    ...
private:
    ...
    static GamePiece EmptyPiece;
    reference_wrapper<GamePiece> _board[N][M] = { ref(Game::EmptyPiece) };
    vector<GamePlayer> _players = vector<GamePlayer>(N_PLAYERS, GamePlayer());
    ...
};

在以下情况中,我希望每个Player持有vector<GamePiece>并返回对这些部分的引用,然后将其放入_board。但是,我_board的以下初始化产生了

  

类“std :: reference_wrapper

”不存在默认构造函数

我在这里缺少什么?在所有权方面,每个GamePlayer都归Game所有(可以看出),而GamePiece肯定归GamePlayer所有,这就是为什么我想使用参考文献。

2 个答案:

答案 0 :(得分:2)

这就是这里

reference_wrapper<GamePiece> _board[N][M] = { ref(Game::EmptyPiece) };

初始化第一个元素(抛出一些大括号),但保留其余的默认值。这不可能发生,因为std::reference_wrapper无法默认初始化(就像它模型化的引用一样)。

您可以将原始数组替换为std::vector N*M大小,并使用相应的构造函数来复制初始化所有元素(就像您对_players所做的那样)。当然,您需要自己进行索引计算,但内存将按顺序排列。

答案 1 :(得分:1)

在我看来,初始化一系列引用很痛苦。问题是,正如@StoryTeller的回答中所述,reference_wrapper不是默认可构造的。

因此,您必须编写自己的解决方法功能。我将为初始化引用数组的一般问题发布代码,而不会深入探讨您的问题。

因此,请考虑以下情况:您有一个数组arr,其中包含支持Game的某种类型的元素(例如,在问题中为operator[])。您需要一个由索引ind指定的对该数组中的元素的const-或非const引用数组。在这里,您去了:

template<typename arr_t, size_t ... I>
auto get_const_reference_array(arr_t const& arr, std::array<size_t, sizeof ...(I)> const& ind, std::index_sequence<I...>)
{
    using T = std::decay_t<decltype(std::declval<arr_t>().operator[](size_t{}))>;
    return std::array<std::reference_wrapper<const T>, sizeof ...(I)> { std::cref(arr[std::get<I>(ind)]) ... };
}
template<typename arr_t, size_t dim>
auto get_const_reference_array(arr_t const& arr, std::array<size_t, dim> const& ind)
{
    return get_const_reference_array(arr, ind, std::make_index_sequence<dim>{});
}

对于非const版本,请删除此代码中的所有const并将std::cref替换为std::ref

用作

std::array<int,5> arr{{1,3,5,7,9}};
std::array<size_t,2> ind{{1,3}};
auto ref_arr = get_const_reference_array(arr, ind);

std::vector<int> vec{{1,3,5,7,9}};
auto ref_vec = get_const_reference_array(vec, ind);
然后

ref_arr是一个大小为2的数组,其中包含对arr[1]arr[3]的const引用,对向量也是如此(但请注意,对向量的引用通常是不稳定的,即通过调整大小或类似的操作,它们可能会失效。