我有std::map<int, std::vector<SomeStruct>>
,
并提供std::vector<SomeStruct> FindData(int key)
之类的查询。
为防止复制整个数据,我将其修改为std::vector<SomeStruct>& FindData(int key)
但是,某些key
没有数据,所以有时我没有任何回报
在这种情况下,我声明一个空std::vector<SomeStruct>
的文件范围变量并将其返回。
但是如果我选择指向vector的指针,那就是std::vector<SomeStruct>* FindData(int key)
,那么我可以为不存在的NULL
返回key
。
哪一个更好?
我在问题(Is there other syntax for this pointer operation?)中了解到指向std::vector
的指针很糟糕(或很奇怪?不确定)
我个人也喜欢引用std::vector
,以便我可以更轻松地使用operator[]
,但缺点是我必须为它声明一个额外的空变量。
代码示例如:SomeClass.h
typedef std::vector<SomeStruct> DataVec;
typedef std::map<int, DataVec> DataMap;
DataMap m_DataMap;
现在在SomeClass.cpp
:
案例1:
namespace
{
DataVec EmptyVector;
}
DataVec& FindDatas(int key)
{
DataMap::iterator It = m_DataMap.find(key);
if (It == m_DataMap.end()) return EmptyVec;
return It->second;
}
案例2:
DataVec* FindDatas(int key)
{
DataMap::iterator It = m_DataMap.find(key);
if (It == m_DataMap.end()) return NULL;
return &(It->second);
}
参考:
优点:看起来很正常std::vector
缺点:声明了附加变量。
指针:
优点:查询功能更短,无需其他变量
缺点:看起来很奇怪(?!),你不能juse p[i]
,你必须(*p)[i]
,这很烦人。
哪一个更好?
答案 0 :(得分:1)
您还可以将输出的引用作为参数,以便您可以添加一些枚举器或bool结果作为方法输出:
namespace
{
DataVec EmptyVector;
}
bool FindDatas(int key, DataVec& output)
{
DataMap::iterator It = m_DataMap.find(key);
if (It == m_DataMap.end()) return false;
output = It->second;
return true;
}
答案 1 :(得分:1)
这取决于您的设计要求。如果使用没有相应元素的索引调用此函数是编程错误,则代码应该中止。如果是用户错误,则应抛出异常。如果它是预期用途的一部分,那么您有三种选择,同样取决于您的设计。您可以标记问题,通常是通过返回空指针或从获取结果引用的函数返回布尔值。您可以像std::set
那样安静地返回新创建的有效对象。您可以返回不属于容器的sentinel对象,用户必须检查这是否是他们在使用返回值之前获得的内容。
答案 2 :(得分:0)
如果您不介意为未完成的密钥创建新条目,则可以使用以下代码:
DataVec& FindDatas(int key)
{
return m_DataMap[key];
}
一种替代方法,可以避免使用未完成密钥的新条目:
DataVec& FindDatas(int key)
{
DataMap::iterator It = m_DataMap.find(key);
if (It == m_DataMap.end()) {
// created on first unfound key and stays
// alive until the end of the program
static DataVec fEmpty;
return fEmpty;
}
return It->second;
}