返回值的C ++函数,需要优化帮助

时间:2015-10-06 10:08:45

标签: c++ c++11 optimization reference

我正在学习C ++,我编写了以下代码:

#include <cstdio>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;

unordered_map<int, vector<uint8_t>> m;

vector<uint8_t> getBitVec(int id)
{
        unordered_map<int, vector<uint8_t>>::const_iterator it = m.find(id);
        if (it != m.cend()) {
                return it->second;
        }
        return vector<uint8_t>();
}

void aND(vector<uint8_t>& dst, const vector<uint8_t>& src)
{
        for (auto i = 0U; i != dst.size(); i++) {
                dst[i] = dst[i] & src[i];
        }
}

// Get a resultant vector of line_item ids from a bit vector of line items
vector<uint16_t> getVec(const vector<uint8_t>& s)
{
        vector<uint16_t> result;
        for (auto i = 0U; i != s.size(); i++) {
                uint8_t temp = (1<<7);
                for (int j = 0; j < 8; j++) {
                        if (s[i] & (temp >> j)) {
                                result.push_back(i * 8 + j);
                        }
                }
        }
        return result;
}


vector<uint16_t> find2(const vector<int>& k)
{
        vector<uint8_t> result;
        bool flag = true;

        for (auto i = 0U; i != k.size(); i++) {
                const vector<uint8_t>& v = getBitVec(k[i]);
                if (v.empty()) {
                        return vector<uint16_t>();
                }
                if (flag == true) {
                        //result = move(v);
                        result = v;
                        flag = false;
                        continue;
                }
                aND(result, v);
        }
        return getVec(result);
}

void init()
{
        m[1].push_back(0xff);
        m[1].push_back(0xfe);

        m[2].push_back(0xf8);
        m[2].push_back(0xf9);

        m[3].push_back(0xf1);
        m[3].push_back(0xf2);
}

int main()
{
        init();
        const auto& t = find2(vector<int>{1, 2, 3});
        for (auto i = 0U; i != t.size(); i++) {
                fprintf(stderr, "\n%d\n", t[i]);
        }
        return 0;
}

基本上我想编写一个函数,该函数返回对非本地“重”对象的引用或空对象的副本。

我正在实现的功能是getBitVec(如URL中所示)。 有人可以判断aND是否会对返回的向量的“临时副本”进行操作,或者不会创建副本。

我相信aND函数将在副本上运行,我想要清除复制的开销,代码不需要副本。但是,如果不更改getBitVec的界面,我可以这样做吗?

这不是一个谜题或假设问题,我不是在寻找像“m”(带有value = vector())存储一个标记密钥并返回对它的引用的技巧,从而将签名更改为 矢量&安培; getBitVect(const vector&amp;)

此代码在C ++ 11中是不是惯用的吗?

我别无选择,只能将指针用作getBitVec的返回类型?

感谢您的耐心等待。

1 个答案:

答案 0 :(得分:0)

如果你需要一个const引用,而不是返回一个空对象的副本,你可以在函数中创建一个空对象的静态本地实例(因此它会在第一次调用函数时创建并保持活动直到程序终止),并返回对此静态空对象的引用。

如果你打算返回非const引用(函数的调用者可能会修改对象),那么最好返回指向对象而不是引用的指针,如果找不到对象则返回nullp。

const vector<uint8_t>& getBitVec(int id)
{
        unordered_map<int, vector<uint8_t>>::const_iterator it = m.find(id);
        if (it != m.cend()) {
                return it->second;
        }
        static const vector<uint8_t> empty_vec;
        return empty_vec;
}

或者

vector<uint8_t>* getBitVec(int id)
{
        unordered_map<int, vector<uint8_t>>::const_iterator it = m.find(id);
        if (it != m.cend()) {
                return &(it->second);
        }
        return nullptr;
}