簡體   English   中英

c ++如何在另一個函數中立即使用函數的返回值作為參考

[英]c++ how to use return value of function immediately in another function as reference

我有以下代碼嘗試通過鏈接對函數combine的調用來組合向量。 我收到錯誤: initial value of reference to non-const must be an lvalue

#include <algorithm>
using namespace std;

vector<int> combine(vector<int>& v1, vector<int>& v2) {
    vector<int> v;
    for(int ele : v1) v.push_back(ele);
    for(int ele : v2) v.push_back(ele);
    return v;
}

int main() {
    vector<int> v1 = {1,2,3};
    vector<int> v2 = {4,5,6};
    vector<int> v3 = {7,8,9};
    combine(v1, combine(v2, v3));
}

為什么會這樣,正確的解決方法是什么?

我擔心這樣做可能會導致不必要的復制:

vector<int> temp = combine(v2, v3);
combine(v1, temp);

您的combine()函數按值返回一個vector ,這意味着它會返回一個臨時對象,一旦調用者完成使用它就會被銷毀。 因此,該函數返回一個右值,並且右值無法綁定到對非 const對象的引用,正如您嘗試做的那樣,因此出現錯誤。

使您的函數參數成為對const對象的引用。 右值可以綁定到const引用。 此外,您的函數不會修改輸入vector s,因此無論如何它們都應該是const

嘗試這個:

#include <algorithm>
using namespace std;

//                   \/                     \/
vector<int> combine(const vector<int>& v1, const vector<int>& v2) {
    vector<int> v;

    // you should add this for good measure:
    // v.reserve(v1.size() + v2.size());

    for(int ele : v1) v.push_back(ele);
    for(int ele : v2) v.push_back(ele);

    // alternatively:
    // v.insert(v.end(), v1.begin(), v1.end());
    // v.insert(v.end(), v2.begin(), v2.end());

    return v;
}

int main() {
    vector<int> v1 = {1,2,3};
    vector<int> v2 = {4,5,6};
    vector<int> v3 = {7,8,9};

    // now this will work as expected...
    vector<int> v4 = combine(v1, combine(v2, v3));

    for(int ele : v4) {
        cout << ele << ' ';
    }
}

輸出:

1 2 3 4 5 6 7 8 9

使參數combine const 解決了最初的問題:

vector<int> combine(const vector<int>& v1, const vector<int>& v2)

但是必須在成對的向量上調用 combine 既低效又難以輸入。 這是我對此的看法:

#include <vector>
#include <concepts>

// make a variadic function so all the combining can be done in one call     
template <typename T, typename... U>
requires (std::same_as<U , std::vector<T>> && ...)         // all U must be vectors of T
std::vector<T> combine(std::vector<T>&& v, U... vs) {      // allow move semantic for arguments
    std::vector<T> res(v.size() + (vs.size() + ...));      // make vector big enough to hold the result
    for(auto && ele : v) res.emplace_back(std::move(ele)); // copy/move first vector
    ([&res](auto && t) {                                   // copy/move the rest
        for(auto && ele : t) res.emplace_back(std::move(ele));
    }(vs), ...);
    return res;                                            // return result with copy elision
}

int main() {
    std::vector<int> v1 = {1,2,3};
    std::vector<int> v2 = {4,5,6};
    std::vector<int> v3 = {7,8,9};
    std::vector<int> c = combine(v1, v2, v3);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM