C++ std::find() 寻址返回向量的类函数时的意外行为
Posted
技术标签:
【中文标题】C++ std::find() 寻址返回向量的类函数时的意外行为【英文标题】:C++ std::find() unexpected behavior when addressing a Class function returning a vector 【发布时间】:2019-07-31 22:37:26 【问题描述】:我是一个理论问题。我有一个类Patient
,其中有一个函数返回类本身的向量Patient.getVars()
class Patient
#... rest of class ...
std::vector<std::string> vVar;
public :
void addVar( std::string var )
vVar.push_back(var);
std::vector<std::string> getVars()
return vVar;
;
#... rest of class ...
我注意到,如果我使用 std::find()
检查向量 vVar
调用类函数的元素:
if ( std::find ( vPatientClass[ posPz ].getVars().begin(), vPatientClass[ posPz ].getVars().end(), var_name ) == vPatientClass[ posPz ].getVars().end() )
# .... rest of code ....
当它实际上是不存在时,它告诉我它是 PRESENT,反之亦然。
否则,如果我复制向量并在其上查找:
std::vector<std::string> vPzVars = vPatientClass[ posPz ].getVars();
if ( std::find ( vPzVars.begin(), vPzVars.end(), var_name ) == vPzVars.end() )
# .... rest of code ....
它的行为符合预期!这对我来说很重要……有什么线索吗?
PS:我通过[ posPz ]
的位置来寻址Patient
对象,因为vPatientClass
是Patient
类对象的向量。
提前感谢您的任何建议!
【问题讨论】:
getVars()
每次调用时都会返回一个副本。这不仅可能会很慢,而且还会导致您看到的问题。在std::find ( vPatientClass[ posPz ].getVars().begin(), vPatientClass[ posPz ].getVars().end(), var_name )
中,您将迭代器传递给两个不同的 向量(同一向量的两个副本),这是不允许的。返回参考:const std::vector<std::string> &getVars() const
所以我可以将矢量公开并直接访问它...对吗?
或者引用返回
你可以保留副本,但要事先有auto patients = vPatientClass[posPz].getVars();
@HolyBlackCat 听起来像是一个答案!
【参考方案1】:
您的getVars
成员正在返回内部向量的副本:
std::vector<std::string> getVars()
return vVar;
;
因此,在您有问题的std::find
调用中,您调用Patient::getVars()
3 次并获得3 个不同的向量副本。虽然值相同,但您从 begin()
和 end()
获得的迭代器彼此不兼容。你可以通过引用返回你的向量:
const std::vector<std::string>& getVars() const
return vVar;
;
【讨论】:
以上是关于C++ std::find() 寻址返回向量的类函数时的意外行为的主要内容,如果未能解决你的问题,请参考以下文章
如何仅通过向量对的第一个元素或自定义向量三元组使用 std::find?
C++,成员函数返回对包含指向 const 对象的指针的向量的 const 引用