C++ 如何使用T&;调用函数;当我有两个T&;和T作为同名函数的返回类型

C++ 如何使用T&;调用函数;当我有两个T&;和T作为同名函数的返回类型,c++,C++,我有一个类,它有两个函数,分别名为Select和returntype,分别是T和T&。我需要用T调用函数&但它总是用返回类型T调用函数。 如何强制它使用T&as返回类型调用函数 这里有两个函数 template <class T> T Array2D<T>::Select(const int& row, const int& column) const { if ((row*this->columns_) + column < 0 ||

我有一个类,它有两个函数,分别名为Select和returntype,分别是T和T&。我需要用T调用函数&但它总是用返回类型T调用函数。 如何强制它使用T&as返回类型调用函数

这里有两个函数

template <class T>
T Array2D<T>::Select(const int& row, const int& column) const
{
    if ((row*this->columns_) + column < 0 || (row*this->columns_) + column >= this->storage_.Length())
    {
        AdtException exception("Index Out of Bound");
        throw exception;
    }
    return this->storage_[(row*this->columns_) + column];
}

template <class T>
T& Array2D<T>::Select(const int& row, const int& column)
{
    if ((row*this->columns_) + column < 0 || (row*this->columns_) + column >= this->storage_.Length())
    {
        AdtException exception("Index Out of Bound");
        throw exception;
    }
    return (this->storage_[(row*this->columns_) + column]);

}


Here is calling code.
template <class T>
T& Row<T>::operator[](const int& column)
{
    T t = this->arr_.Select(row_, column);
    T& t1 = t;
    return t1;
}

template <class T>
T Row<T>::operator[](const int& column) const
{
    return this->arr_.Select(row_, column);
}
模板
T Array2D::Select(const int&row,const int&column)const
{
如果((行*this->columns_)+column<0 ||(行*this->columns_)+column>=this->storage_.Length())
{
AdtException异常(“索引越界”);
抛出异常;
}
返回此->存储\[(行*此->列\)+列];
}
模板
T&Array2D::选择(常量整型&行,常量整型&列)
{
如果((行*this->columns_)+column<0 ||(行*this->columns_)+column>=this->storage_.Length())
{
AdtException异常(“索引越界”);
抛出异常;
}
返回(此->存储\[(行*此->列\)+列];
}
这是呼叫代码。
模板
T&Row::运算符[](常量int和列)
{
T T=此->排列。选择(行、列);
T&t1=T;
返回t1;
}
模板
T行::运算符[](常量int和列)常量
{
返回此->排列。选择(行、列);
}
这里是接口

class IRow
{
public:
    virtual ~IRow() = default;
    virtual T& operator[](const int& column) = 0;
    virtual T operator[](const int& column) const = 0;
};

class IArray2D
{
public:
    virtual ~IArray2D() = default;
    virtual T Select(const int& row, const int& column) const noexcept(false) = 0;
    virtual T& Select(const int& row, const int& column) noexcept(false) = 0;
    virtual Row<T> operator[](const int& row) const noexcept(false) = 0;
    virtual Row<T> operator[](const int& row) noexcept(false) = 0;
    virtual explicit operator bool() const noexcept = 0;
    virtual size_t Rows() const noexcept = 0;
    virtual size_t Columns() const noexcept = 0;
    virtual void Rows(const size_t& rows) noexcept(false) = 0;
    virtual void Columns(const size_t& columns) noexcept(false) = 0;
};
class-IRow
{
公众:
virtual~IRow()=默认值;
虚拟T运算符[](常量int和列)=0;
虚拟T运算符[](常量int和列)常量=0;
};
类IArray2D
{
公众:
virtual~IArray2D()=默认值;
虚拟T选择(常量int和行、常量int和列)常量noexcept(false)=0;
虚拟T&Select(常量int&row,常量int&column)noexcept(false)=0;
虚拟行运算符[](const int&Row)const noexcept(false)=0;
虚拟行运算符[](const int&Row)noexcept(false)=0;
虚拟显式运算符bool()const noexcept=0;
虚拟大小_t Rows()常量noexcept=0;
虚拟大小\u t Columns()常量noexcept=0;
虚空行(const size_t&Rows)无异常(false)=0;
虚拟空列(常量大小和列)无异常(false)=0;
};

通常不能根据返回类型重载方法,因为调用者无法指定要哪个重载。但是,在您的例子中,方法是使用限定符重载的:一个
const
另一个不是。这意味着为了调用
const
版本,您需要调用
const
对象上的方法,而非
const
版本则相反。例如:

// this will call the T Select(...) const because the array is const
static_cast<const Array2D<T> &>(_arr).Select(_row, column);
//这将调用T Select(…)const,因为数组是const
静态强制转换(arr)。选择(行、列);

您是否使用过赋值左侧显示的
运算符[]
?此外,您在返回引用的函数中有一个致命缺陷:变量
t
是一个局部变量,它将结束函数的生命周期,您返回对该局部变量的引用。您只需执行
返回此->存储\[(行*此->列)+列]与在其他函数中一样。您的
运算符[]
也应该具有
const
重载,但您只有非const版本。您意识到,如果对常量
对象调用,使用
[]
的代码将不会编译,对吗?您的测试程序是否执行以下操作:
void foo(const Array2D&x){x[0];}
或类似的操作,并尝试调用
foo
?如果你尝试这样做,你就会明白我的意思。让我们从第一步开始,问一个简单的问题——为什么你总是返回对象而不是引用?如果类的用户需要副本,那么他们可以通过简单地调用函数来实现,并且在
=
的左侧,他们指定一个对象而不是引用。您无需手持并尝试将对象返回给调用者——调用者可以完全控制对象。再说一遍,
vector
如何完美地工作,而您的类却不工作?为什么不完全删除
Select
(返回项目副本的实现)的第一个实现,然后使用它呢?然后像其他人建议的那样,应用关于返回堆栈变量引用的修复。const IArray2D&arr_u我必须用它调用非const方法。请告诉我如何做到这一点。@AmmadIslam,在这种情况下,这是一个设计缺陷,因为您不能对const对象调用非const方法。当然,你可以像这样扔掉常数,但这是一个非常糟糕的做法,应该不惜任何代价避免,我怀疑这是你的教授想要的。如果此
arr\uu
成员是您不能更改的代码部分,则这似乎是练习中的一个错误,除非练习的目的是发现此错误。非常感谢,先生。你是救世主。非常感谢你,先生。你是一个救世主,同时,你的教授是一个C++职业杀手。如果你打算用一种糟糕的教学方式来获得一个C++的工作,你就麻烦了。是的,先生,我理解,但它的任务,我必须通过。