7

我有一个std::map<int, std::vector<SomeStruct>>
并提供一个类似的查询std::vector<SomeStruct> FindData(int key)

为了防止复制整个数据,我将其修改为std::vector<SomeStruct>& FindData(int key).
但是,肯定不会有数据key,所以有时我没有什么可以返回的。
在这种情况下,我声明一个为空的文件范围变量std::vector<SomeStruct>并返回它。

但是,如果我选择指向向量的指针,std::vector<SomeStruct>* FindData(int key)那么我可以只返回NULL不存在的key.

哪一个更好?
我在问题中了解到指针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;
}

案例二:

DataVec* FindDatas(int key)
{
    DataMap::iterator It = m_DataMap.find(key);

    if (It == m_DataMap.end()) return NULL;

    return &(It->second);
}

参考:
优点:看起来很正常std::vector
缺点:声明了附加变量。

指针:
优点:查询功能更短,不需要其他变量。
缺点:看起来很奇怪(?!),你不能开玩笑p[i],你必须这样做(*p)[i],这很烦人。

哪一个更好?

4

3 回答 3

1

你也可以给输出的引用作为参数,这样你就可以添加一些枚举器或布尔结果作为方法输出:

    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;
    }
于 2013-03-30T07:47:41.633 回答
1

这取决于您的设计要求。如果使用没有对应元素的索引调用此函数是一个编程错误,那么代码应该中止。如果是用户错误,它应该抛出异常。如果它是预期用途的一部分,那么您有三种选择,同样取决于您的设计。您可以标记问题,通常通过返回空指针或从获取结果引用的函数返回布尔值。您可以像这样悄悄地返回一个新创建的有效对象std::set。您可以返回一个不属于您的容器的哨兵对象,用户在使用返回值之前必须检查这是否是他们得到的。

于 2013-03-30T13:19:28.273 回答
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;
}
于 2013-03-30T03:34:47.320 回答