【问题标题】:Read-only variable is not assignable c++ template function只读变量不可赋值 c++ 模板函数
【发布时间】:2015-10-26 09:13:29
【问题描述】:

我正在尝试编写自己的模板交换函数,但这段代码有问题:

template <class T>
void swap_universal(T &a, T &b) {
    T tmp = a;
    a = b;
    b = tmp;
}

在这两行:a = bb = tmp 我收到错误 read only variable is not assignable。我正在使用 Xcode。

UPD:这是完整的代码:

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <iterator>

using namespace std;

template <class T>
void swap_universal(T &&a, T &&b) {
    T tmp = a;
    a = b;
    b = tmp;
}

template <typename T>
void quick_Sort(const int &start, const int &end, const vector<T> &mas/*, const vector<T> arr*/) {
    int left = start, right = end;
    int middle = rand() % (end - start) + start;
    while (left < right) {
        while (mas[left] < middle)
        left++;
        while (mas[right] > middle)
            right--;
        if (left <= right) {
            swap_universal(mas[left], mas[right]);
            left++;
            right--;
        }
    }
    if (start < right)
        quick_Sort(start, right, mas);
    if (end > left)
        quick_Sort(left, end, mas);
}

int main(int argc, const char * argv[]) {
    vector<int> t;
    for (int i = 100; i >= 0; i--) {
        t.push_back(i);
    }
    quick_Sort(0, t.size() - 1, t);
}

如您所见,quick_Sort 函数内部调用了新的交换函数

【问题讨论】:

  • 你用什么调用这个函数?
  • 请编辑您的问题以包含Minimal, Complete, and Verifiable Example。还包括实际、完整且未经编辑的错误输出。
  • 您正在使用 const 对象作为参数调用函数
  • std::swap 有什么问题?
  • 向量mas是对常量向量的引用,你不能修改它。在参数声明中删除 const 关键字。

标签: c++ template-function


【解决方案1】:

我认为无需查看呼叫站点,我们就可以推断出发生了什么。

临时不能绑定到可变左值引用。它可以绑定到可变 r 值引用或 const 引用。

所以当调用你的函数时,这是一个无法编译的例子:

extern Foo make_a_new_foo();
Foo f;
swap_universal(f, make_a_new_foo());

const 引用对你没有好处,因为你想修改引用。所以你真正想要的是一个模板函数,它根据上下文推断 a 和 b 是右值引用还是左值引用。

幸运的是,当您在推导上下文中指定 r 值引用语法时,c++ 为您处理了这个魔法(在这种情况下,T 在推导上下文中被评估,因为它的类型取决于为 T 选择正确的类型)。

这将起作用:

template <class T, class U, typename = std::enable_if_t<std::is_same<std::decay_t<T>, std::decay_t<U>>::value>>
void swap_universal(T &&a, U &&b) {
    T tmp = a;
    a = b;
    b = tmp;
}

【讨论】:

  • 这个答案相当具有误导性。带有Foowouldn't compile 的代码,但由于OP 声称的不同原因:在这种情况下永远无法推断出const。并且 forwarding-reference 案例实际上并不使用转发,因此它会在仅移动类型时相当神秘地失败。
  • @Angew 您的链接示例与我的答案不匹配。
  • 那我误解了你的回答。我把它当作“(a)这里是 OP 的代码会显示 OP 错误的代码,以及(b)这里是如何解决它。”但是您显示的第一个代码 not 显示 OP 的错误。
  • 首先,感谢您就此展开对话。结果,我发现我的第一个解决方案(已修复)存在问题。经过反思,我接受了你的立场。我对 OP 特定用例的假设是不正确的。话虽如此,我仍然提供答案,因为(修改后的)交换功能在我看来很可能接近 OP 想要的。 (即适用于右值和左值引用的交换)
  • 这似乎不太可能是解释;这将给出关于绑定失败的错误,而不是const 问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多