【问题标题】:Why do I get this lvalue & rvalue error while using a void function in C++?为什么在 C++ 中使用 void 函数时会出现左值和右值错误?
【发布时间】:2023-01-20 17:03:41
【问题描述】:

我正在做这个练习 18.7C++ 入门加(第 6 版):

我给出的代码是这样的,根据需要使用 lambda 表达式:

#include <iostream>
#include <array>
#include <algorithm>

const int Size = 5;

template <typename T>
void sum(std::array<double, Size> a, T& fp);

int main()
{
    double total = 0.0;

    std::array<double, Size> temp_c = {32.1, 34.3, 37.8, 35.2, 34.7};
    sum(temp_c, [&total](double w){ total += w; });
    std::cout << "total: " << total << std::endl;
    std::cin.get();
    return 0;
}

template <typename T>
void sum(std::array<double, Size> a, T& fp)
{
    for (auto pt = a.begin(); pt != a.end(); ++pt)
        fp(*pt);
}

我用VSCode编译后,报错了: cannot bind non-const lvalue reference of type 'main(int, char**)::&lt;lambda(double)&gt;&amp;' to an rvalue of type 'main(int, char**)::&lt;lambda(double)&gt;'。我也查看了官方的答案,它和我的代码几乎一样,并且在编译时给出了同样的错误。我想这是因为void类型函数与模板函数sum中调用的T&amp;类型不匹配,但是问题中要求如何修改代码,同时保持原sum()函数不变呢?我也很困惑为什么会有左值和右值问题在这里。

提前感谢任何答案和解释。

【问题讨论】:

  • 提示:如果您将 typedef 替换回错误消息,它看起来像 cannot bind non-const lvalue reference of type 'T&amp;' to an rvalue of type 'T'。是不是比较熟悉?例如,您是否尝试过声明foo(int&amp; x) 然后调用foo(1);?看看同样的问题是如何发生的?

标签: c++ lambda rvalue lvalue


【解决方案1】:

问题是您将临时(lambda [&amp;total](double w){ total += w; })传递给需要非常量左值引用的函数。那些不能绑定到临时对象,例如您在这里经过的那个。

写作

template <typename T>
void sum(std::array<double, Size> a, T fp)

应该做的伎俩。

顺便说一句,最好通过const&amp; 传递数组以避免复制:

template <typename T>
void sum(const std::array<double, Size>& a, T fp)

【讨论】:

  • 基本上与我的答案相同 :-) 请注意,尽管赋值表示不能修改总和,因此这里的非理想解决方案是将 lambda 赋值给一个变量。
【解决方案2】:

通过内联定义 lambda,您已将其设为临时的右值。这意味着因为模板将函数指针作为非常量引用(呃!),所以没有转换——右值不能绑定到左值参数,所以它不能编译。 如果将 lambda 提取到它自己的变量中,它会起作用:

#include <iostream>
#include <array>
#include <algorithm>

const int Size = 5;

template <typename T>
void sum(std::array<double, Size> a, T& fp);

int main()
{
    double total = 0.0;

    std::array<double, Size> temp_c = {32.1, 34.3, 37.8, 35.2, 34.7};
    auto l = [&total](double w){ total += w; };
    sum(temp_c, l);
    std::cout << "total: " << total << std::endl;
    std::cin.get();
    return 0;
}

template <typename T>
void sum(std::array<double, Size> a, T& fp)
{
    for (auto pt = a.begin(); pt != a.end(); ++pt)
        fp(*pt);
}

即使赋值明确表示不适应 sum(),如果将 fp 参数转换为 const ref,原始临时变量也会编译。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多