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

C++ 有关运算符[]的编译错误,c++,operators,rvalue,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)

我创建了一个模板类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矢量水电站
#定义矢量水电站
#包括
模板
类向量
{
公众:
向量(int=0);
~vect();
无效显示(无效)常数;
无效排列(int,int);
T&operator[](国际);
常量T和运算符[](int)常量;
void init_perm(void);
私人:
int n;
双*p;
std::向量s;
};
#endif/*保护向量水电站*/
#包括“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
\ifndef向量CPP
#定义向量CPP
#包括“向量hpp”
#包括
使用名称空间std;
模板
向量:向量(整数a):n(a)
{
p=新的双精度[n];
s、 调整大小(n);
init_perm();
}
模板
vect::~vect()
{
删除[]p;
}
模板
void向量::显示(void)常量
{
对于(int i=0;icout问题源于与模板
T
相比
p
的类型不匹配

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

编译器会为您执行到
int
的转换,但此转换后的值是右值和临时值,引用不能绑定到右值


解决方案是不存在类型不匹配,而是让
p
指向
T
的数组。或者更好的是,让它成为
std::vector
与模板
T
相比,问题源于
p
的类型不匹配

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

编译器会为您执行到
int
的转换,但此转换后的值是右值和临时值,引用不能绑定到右值

解决方案是不存在类型不匹配,而是让
p
指向
T
的数组。或者更好的是,让它成为
std::vector

问题在于:

template <class T>
T& vect<T>::operator[](int i)
{
    return p[s[i-1]-1];
}
模板
T&vect::运算符[](int i)
{
返回p[s[i-1]-1];
}
在您的示例中,
T
被推断为
int
,但是
p
始终是
double
类型。因此,当您返回
p[s[i-1]-1]
,一个
int&
试图绑定到一个
double
。此时
double
值隐式转换为一个不能绑定到
int&
的右值
int
,问题在于:

template <class T>
T& vect<T>::operator[](int i)
{
    return p[s[i-1]-1];
}
模板
T&vect::运算符[](int i)
{
返回p[s[i-1]-1];
}

在您的示例中,
T
被推断为
int
,但是
p
始终是
double
类型。因此,当您返回
p[s[i-1]-1]
,一个
int&
试图绑定到一个
double
。在这一点上,
double
值隐式转换为一个右值
int
,它不能绑定到
int&

通常数组和向量索引是零基的。为什么要将它更改为一基向量索引?
double*p
-为什么?
double*p;
必须是
T*p;
。听起来像是打字错误。
p
double*
。对
p[i]的引用
无法转换为对
int
@Someprogrammerdude的引用。我是数学专业的学生,学习数值线性代数。我们习惯于用一个索引来表示向量,而不是零个索引。事实上,这并不是一个真正的问题,但在阅读程序时,对我们来说很不方便,因为我们总是用o来表示向量基于ne的索引。通常数组和向量索引是基于零的。为什么要将其更改为基于一的向量索引?
double*p;
-为什么?
double*p;
需要是
T*p;
。听起来像是一个输入错误。
p
是一个
double*
。对
p[i]的引用
无法转换为对
int
@Someprogrammerdude的引用。我是数学专业的学生,学习数值线性代数。我们习惯于用一个索引来表示向量,而不是零个索引。事实上,这并不是一个真正的问题,但在阅读程序时,对我们来说很不方便,因为我们总是用o来表示向量基于ne的索引。非常感谢你的回答!你是对的,我应该声明
p
T*
而不是
double*
。非常感谢你的回答!你是对的,我应该声明
p
T*
而不是
double*
。非常感谢你的回答!你是对的,我应该决定是
p
as
T*
而不是
double*
。非常感谢你的回答!你是对的,我应该声明
p
T*
而不是
double*
template <class T>
T& vect<T>::operator[](int i)
{
    return p[s[i-1]-1];
}