从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
所有,这就是为什么我想使用参考文献。
答案 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引用,对向量也是如此(但请注意,对向量的引用通常是不稳定的,即通过调整大小或类似的操作,它们可能会失效。