-2

我正在开发一个 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将元素添加到向量中。我想将元素添加到lvalue名为 actual( ) 的向量vec中,但将元素添加到rvalue. 有没有办法将元素添加到名为vecusing的向量中std::any如果没有,那么还有其他方法可以做到这一点,例如使用std::variant或其他我可能不知道的方法。我正在寻找一种在任何版本的 C++(如 C++11 或 C++17 等)中执行此操作的方法。

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

4

2 回答 2

2

我们在右值上使用 push_back

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

如果要在 中存储对对象的引用,则需要通过存储指向该对象any的指针或 a 来显式执行此操作: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);

请注意,使用anywhich 引用对象是危险的。如果any引用对象的生命周期超过了被引用对象的生命周期,那么当您尝试访问被引用对象时,您会遇到不好的事情。这就是为什么any默认存储副本的部分原因。

于 2021-12-16T15:10:42.090 回答
1

你错过了一个参考:

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

目前,您使用std::any_cast.

注意:正如尼可波拉斯所指出的,这只是避免了演员表的复制,但不避免复制初始std::vector进入。std::any

于 2021-12-16T15:11:08.920 回答