有关运算符[]的编译错误

时间:2017-02-10 06:43:32

标签: c++ operators rvalue

我创建了一个模板类vect,它允许我创建T类型的元素数组,从1到n(而不是0到n-1)访问它们并置换它们(我必须以这种方式置换它们而不是置换它们他们是经典的方式。)

这是头文件:

#ifndef VECT_HPP

#define VECT_HPP

#include <vector>

template <class T>
class vect
{
public:
    vect(int=0);
    ~vect();
    void show(void) const;
    void permute(int,int);
    T& operator[](int);
    const T& operator[](int) const;
    void init_perm(void);
private:
    int n;
    double* p;
    std::vector<int> s;
};

#endif /* GUARD_VECT_HPP */
#include "vect.cpp"

以及源文件:

#ifndef VECT_CPP
#define VECT_CPP

#include "vect.hpp"
#include <iostream>

using namespace std;

template <class T>
vect<T>::vect(int a): n(a)
{
    p=new double[n];
    s.resize(n);
    init_perm();
}

template <class T>
vect<T>::~vect()
{
    delete [] p;
}

template <class T>
void vect<T>::show(void) const
{
    for (int i = 0; i < n; i++)
        cout << p[i] << endl;
}

template <class T>
void vect<T>::permute(int a,int b)
{
    static int c;
    a--;
    b--;
    c=s[a];
    s[a]=s[b];
    s[b]=c;
}
template <class T>
T& vect<T>::operator[](int i)
{
    return p[s[i-1]-1];
}

template <class T>
const T& vect<T>::operator[](int i) const
{
    return p[s[i-1]-1];
}

template <class T>
void vect<T>::init_perm(void)
{
    for (int i = 0; i < n; i++)
        s[i]=i+1;
}

#endif

这里是我用来测试该类的文件main.cpp:

#include "vect.hpp"
#include <iostream>

using namespace std;

int main(void)
{
    vect<int> v(5);
    v.show();
    for (int i = 1; i <=5; i++)
        v[i]=10*i;
    v.show();
    cout << "Permuted 3 and 5" << endl;
    v.permute(3,5);
    v.show();
    v.init_perm();
    cout << "Initialized permutations" << endl;
    v.show();
    return 0;
}

我收到以下错误:

In file included from vect.hpp:25:0,
                 from main.cpp:1:
vect.cpp: In instantiation of ‘T& vect<T>::operator[](int) [with T = int]’:
main.cpp:11:6:   required from here
vect.cpp:43:19: error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’
  return p[s[i-1]-1];

我在互联网上搜索了这个错误以及它是如何由operator[]的错误实现引起的,但是在纠正后我仍然有同样的错误,即使我返回p[i-1]而不是{{ 1}}。

你能帮我吗?

2 个答案:

答案 0 :(得分:2)

问题源于p与模板T相比的类型不匹配。

double指向的数组p。模板Tint。通常这不是一个大问题,因为double可以隐式转换为int。但这不是正常情况,因为您希望将引用返回到int

编译器为您执行转换为int,但此转换后的值是 rvalue 和临时值,并且引用无法绑定到rvalues。

解决方案是不要使用类型不匹配,并且p指向T数组。或者更好的是,让它成为std::vector

答案 1 :(得分:2)

问题在于:

template <class T>
T& vect<T>::operator[](int i)
{
    return p[s[i-1]-1];
}

在您的示例中,T推断为int,但p始终为double类型。因此,当您返回p[s[i-1]-1]时,int&会尝试绑定到double。此时,double值会隐式转换为无法绑定到int的右值int&