【问题标题】:How to overload [] for a templated function如何为模板函数重载 []
【发布时间】:2021-02-16 09:12:56
【问题描述】:

我的任务是通过实现具有各种功能的数组类来改进 C 数组。我正在尝试重载“[]”,但遇到了问题。

template<typename T>
class SA{
private:
  T* pT;
//other vars...

public: 
//other initialization functions...
int& operator [](int offset);
};

template<typename T>
int& SA<T>::operator [](int offset){
  if (offset < lIdx || offset > hIdx){
    std::cout << "invalid index:" << std::endl;
  }

  return pT[offset];
}

int main(){
  SA<float> thing1(15);
  thing1[5] = 5;
  return 0;

当我使用这个重载函数时,我遇到了这个错误:

错误:无法将“int&”类型的非常量左值引用绑定到 “int”类型的右值

但是,如果我理解正确,如果删除“&”,则无法使用“=”重新分配该索引的值。如果我这样做,编译器也会抛出这个错误:

错误:需要左值作为赋值的左操作数

我应该在这里做什么?

【问题讨论】:

  • 返回类型不应该是T&amp;而不是int&amp;吗?
  • 数组的类型为float,但您的operator[] 正试图返回int&amp;
  • 当您将此模板类用于const int 值类型时,问题出在返回类型上。尝试为此添加另一个重载
  • 如果偏移量不在范围内,抛出异常std::out_of_range而不是让程序崩溃
  • @Wander3r:不,崩溃非常合理。投掷变体应该命名为at(),就像std::vector::atstd::array::at。数组类是非常原始的构建块,添加无法访问的异​​常代码会减慢很多代码。

标签: c++ templates overloading


【解决方案1】:

函数的返回类型应该是T&amp;,而不是int&amp;

T& operator [](int offset);

还要注意,虽然检查以确保索引在范围内是件好事,但实际上您并没有对此做任何事情。一种解决方案是抛出异常:

#include <stdexcept>

template <typename T>
T& SA<T>::operator[](int offset) {
  if (offset < lIdx || offset > hIdx)
    throw std::out_of_range{"Array index out of range"};
  return pT[offset];
}

如果您真的想与 STL 容器保持一致,请取消选中 operator[],并添加调试时检查,例如:

#include <cassert>

template <typename T>
T& SA<T>::operator[](int offset) noexcept { // note noexcept
  assert(offset < lIdx || offset > hIdx);
  return pT[offset];
}

添加这个运算符的 const-overload 也很好:

const T& operator [](int offset) const noexcept;

【讨论】:

  • 谢谢!这就是问题所在。这个断言也是一个非常酷的补充!
【解决方案2】:

首先你应该根据你的值类型调整返回类型:

template<typename T>
T& SA<T>::operator [](int offset){
  if (offset < lIdx || offset > hIdx){
    std::cout << "invalid index:" << std::endl;
  }

  return pT[offset];
}

如果你希望它也可以在常量模式下工作,请添加以下重载:

template<typename T>
const T& SA<T>::operator [](int offset)const{
  if (offset < lIdx || offset > hIdx){
    std::cout << "invalid index:" << std::endl;
  }

  return pT[offset];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-04
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多