繁体   English   中英

std :: function中不允许引用返回类型吗?

[英]Is reference return type not allowed in std::function?

当我试图设置旁路函数参数时,我发现给定的引用返回类型会因为无效地址而带来SEGV。 我有一个你可以玩的玩具代码。 当我用指针替换引用返回类型时,一切正常。

/* This doc is to investigate the issue brought by reference return type of a
 * functor argument std::function. We expect it can pass the bypass function
 * defined in top layer to less-context bottom layer and still work as designed.
 * However we see weird behavior when it is std::function<const std::string&(int)>.
 * Instead, std::function<const string*(int)> works fine...
*/
#include <iostream>
#include <vector>
#include <unordered_map>
#include <string>
#include <functional>

using namespace std;

// This class stores vectror of numbers and divisors. API getRemainderRing picks
// those numbers' remainder equal to given number after division. Bypass function
// is passed in as argument to print the names.
class Elements {
public:
    Elements() = default;
    Elements(int32_t maxNum, int32_t divisor) : _div(divisor) {
        _data.clear();
        _data.reserve(maxNum);
        for (int32_t i = 0; i < maxNum; i++) {
            _data.push_back(i);
        }
    }

    void getRemainderRing(int32_t rmd, const std::function<const string&(int32_t)>& getName, string* output) {
        output->clear();
        for (int32_t i : _data) {
            if (i % _div == rmd) {
                // crashes here. getName(i) pointing to address 0
                *output += getName(i) + " ";
            }
        }
    }

private:
    vector<int32_t> _data;
    int32_t _div;
};

int main () {
    unordered_map<int32_t, string> numToStr;
    numToStr[0] = "null";
    numToStr[1] = "eins";
    numToStr[2] = "zwei";
    numToStr[3] = "drei";
    numToStr[4] = "vier";

    // The functor
    std::function<const string&(int32_t)> getName = [&numToStr](int32_t i) { return numToStr[i]; };

    Elements smallRing(4, 2); // contains {0,1,2,3}, divisor: 2
    string result;
    // This is actually to get all odd numbers < 4
    smallRing.getRemainderRing(1, getName, &result);

    // BOOM!
    cout << result << endl;

    return 0;
}

我希望输出为“eins drei”。 我检查了std :: function https://en.cppreference.com/w/cpp/utility/functional/function的文档,没有提到返回类型R不能作为参考。 我想知道这是否是规范中的已知缺陷/漏洞,或者我在使用它时犯了一些愚蠢的错误。

你的lambda没有指定一个返回类型,因此它被推断为按值返回一个string ,而不是你想要的const string&引用。 如果你使lambda返回const string&显式,那么SEGV将不再发生:

[&numToStr](int32_t i) -> const string& { return numToStr[i]; }

现场演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM