如何使用 std::any 将元素添加到 std::vector

How to Add Element into a std::vector using std::any

我正在开发一个 C++17 项目,我正在使用 std::any。下面给出了一个最小的可重现示例,以供参考,解释我想要实现的目标。

#include <any>
#include <vector>
#include <iostream>
int main()
{
    std::vector<int> vec{1,2,3};
    
    std::any anything = vec;
    
   // anything.push_back(4);//i want to add an element into vector vec, using variable anything but this statement won't work

    
    std::cout<<std::any_cast<std::vector<int>>(anything).size()<<std::endl;//prints 3 
    std::any_cast<std::vector<int>>(anything).push_back(4);//this adds(push_back) element into rvalue
    std::cout<<std::any_cast<std::vector<int>>(anything).size()<<std::endl;//prints 3 but i want 4 
}

如上例所示,我有一个 std::any 对象,我正在使用 std::any_cast 将元素添加到向量中。我想将该元素添加到名为 vec 的实际 (lvalue) 向量中,但相反,该元素被添加到 rvalue 中。 有没有一种方法可以使用 std::any. 将元素添加到名为 vec 的向量中?如果没有,那么有没有其他方法可以做到这一点,比如使用 std::variant 或其他我可能不知道的东西。我正在寻找一种在任何版本的 C++(如 C++11 或 C++17 等)中执行此操作的方法。

在我的实际项目中,有存储任意类型对象的需求。所以我在那里遇到了同样的问题。然后意识到出了什么问题(即,我们在右值上使用 push_back),然后我将问题简化为最小的可重现示例,并在这里提问。

we are using push_back on an rvalue

不,这不是问题所在。 any 存储给定内容的 copy。它不引用其他一些对象。它根据给定的内容创建一个对象。因此,即使您获得了对 any 中对象的引用,它也不会是对 vec 本身的引用。

如果您想在 any 中存储对对象的引用,您需要通过存储指向该对象的指针或 reference_wrapper 来明确地这样做:

using ref_type = decltype(std::ref(vec));

std::any anything = std::ref(vec);

std::any_cast<ref_type>(anything).get().push_back(4);

请注意,拥有一个引用对象的 any 是危险的。如果 any 超过了被引用对象的生命周期,当您尝试访问被引用对象时,您会遇到麻烦。这就是 any 默认存储副本的部分原因。

您错过了一个参考:

std::any_cast<std::vector<int>&>(anything).push_back(4);
//                            ^

目前,您使用 std::any_cast 创建副本。

注意: 正如 Nicol Bolas 所指出的,这只会避免演员的复制,但不会避免将初始 std::vector 复制到 std::any