如何在 C++ 中将对来自一个向量的对象的引用存储在另一个向量中?
How to store references to objects from one vector in another vector in C++?
我有一个向量 std::vector<MyClass> myclass_vec(10)
,其中包含 MyClass
的 10 个初始化对象。现在我想遍历这个向量并将对每个 MyClass
对象的引用存储在另一个向量 std::vector<MyClass> myclass_vec_refs
中。我想存储引用的原因是因为我不必复制对象,显然,引用与 myclass_vec
.
中相同的对象
出于某种原因,这无法按方面进行。我必须像这样声明 std::vector<&MyClass> myclass_vec_refs
吗?
当我浏览这里提出的其他问题时,我读到了 std::unique_ptr
。如果我更改 std::vector<std::unique_ptr<MyClass>> myclass_vec(10)
那么我将无法在 myclass_vec_refs
中拥有引用或指针,因为它们被声明为唯一的。如果我弄错了,请纠正我。
另一种方法是使用 std::shared_ptr
。因为它有一个引用计数器,所以我可以让 myclass_vec_refs
指向 myclass_vec
中的对象,但我读到这引入了相当多的开销,并且 share_ptr 应该只作为最后的手段使用。
我也不知道像我尝试的那样引用是否可行。如果 myclass_vec
中的对象被删除会怎样? myclass_vec_refs
向量的大小是否调整为 -1 因为对象不再存在或者它只是指向错误的内存?
是否可以在 myclass_vec_refs
向量中 emplace_back
引用?由于这会就地创建对象,我想这不起作用,只能使用 push_back
?
您不能创建引用向量。
为什么?
引用必须始终引用实际对象,设计的向量必须能够为您动态创建 "empty" 个对象(即默认构造函数)。
但是您可以创建一个指针向量。
如果以任何方式修改了另一个向量,您的指针将失效。
如果这对您来说是个问题,请改用 map 或 set。
正如这里的回答:Strange Template Deduction
诀窍是使用std::reference_wrapper<>
#include <algorithm>
#include <iostream>
#include <vector>
template<typename container_ty_, class Comp>
auto where(container_ty_& V, Comp&& comp)
{
using value_type = typename container_ty_::value_type;
using reference =
std::conditional_t<
std::is_const<container_ty_>::value,
std::reference_wrapper<const value_type>,
std::reference_wrapper<value_type>
>;
std::vector<reference> cursor;
for(auto& VAL : V)
if(comp(VAL))
cursor.push_back(VAL);
return cursor;
}
int main(int argc, char** argv) {
std::vector<int> tVect = {0, 5, 2, 1, 7, 9};
//Why must std::vector<int> be passed...
auto vec = where(tVect, [](const int& V) -> bool { return V > 5; });
std::for_each(vec.begin(), vec.end(), [] (int& v) { std::cout << v++ << std::endl; });
std::cout << std::endl;
std::for_each(tVect.begin(), tVect.end(), [](const int& v) { std::cout << v << std::endl; });
}
我有一个向量 std::vector<MyClass> myclass_vec(10)
,其中包含 MyClass
的 10 个初始化对象。现在我想遍历这个向量并将对每个 MyClass
对象的引用存储在另一个向量 std::vector<MyClass> myclass_vec_refs
中。我想存储引用的原因是因为我不必复制对象,显然,引用与 myclass_vec
.
出于某种原因,这无法按方面进行。我必须像这样声明 std::vector<&MyClass> myclass_vec_refs
吗?
当我浏览这里提出的其他问题时,我读到了 std::unique_ptr
。如果我更改 std::vector<std::unique_ptr<MyClass>> myclass_vec(10)
那么我将无法在 myclass_vec_refs
中拥有引用或指针,因为它们被声明为唯一的。如果我弄错了,请纠正我。
另一种方法是使用 std::shared_ptr
。因为它有一个引用计数器,所以我可以让 myclass_vec_refs
指向 myclass_vec
中的对象,但我读到这引入了相当多的开销,并且 share_ptr 应该只作为最后的手段使用。
我也不知道像我尝试的那样引用是否可行。如果 myclass_vec
中的对象被删除会怎样? myclass_vec_refs
向量的大小是否调整为 -1 因为对象不再存在或者它只是指向错误的内存?
是否可以在 myclass_vec_refs
向量中 emplace_back
引用?由于这会就地创建对象,我想这不起作用,只能使用 push_back
?
您不能创建引用向量。 为什么?
引用必须始终引用实际对象,设计的向量必须能够为您动态创建 "empty" 个对象(即默认构造函数)。
但是您可以创建一个指针向量。
如果以任何方式修改了另一个向量,您的指针将失效。 如果这对您来说是个问题,请改用 map 或 set。
正如这里的回答:Strange Template Deduction
诀窍是使用std::reference_wrapper<>
#include <algorithm>
#include <iostream>
#include <vector>
template<typename container_ty_, class Comp>
auto where(container_ty_& V, Comp&& comp)
{
using value_type = typename container_ty_::value_type;
using reference =
std::conditional_t<
std::is_const<container_ty_>::value,
std::reference_wrapper<const value_type>,
std::reference_wrapper<value_type>
>;
std::vector<reference> cursor;
for(auto& VAL : V)
if(comp(VAL))
cursor.push_back(VAL);
return cursor;
}
int main(int argc, char** argv) {
std::vector<int> tVect = {0, 5, 2, 1, 7, 9};
//Why must std::vector<int> be passed...
auto vec = where(tVect, [](const int& V) -> bool { return V > 5; });
std::for_each(vec.begin(), vec.end(), [] (int& v) { std::cout << v++ << std::endl; });
std::cout << std::endl;
std::for_each(tVect.begin(), tVect.end(), [](const int& v) { std::cout << v << std::endl; });
}