简体   繁体   English

如何为模板化的 function 重载 []

[英]How to overload [] for a templated function

I'm tasked with improving C arrays by implementing an array class with various functionality.我的任务是通过实现具有各种功能的数组 class 来改进 C arrays。 I'm trying to overload '[]' but I've ran into an issue.我试图超载 '[]' 但我遇到了问题。

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;

When I use this overloading function, I'm met with this error:当我使用这个重载 function 时,我遇到了这个错误:

error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'错误:无法将“int&”类型的非常量左值引用绑定到“int”类型的右值

However, if I understand correctly I can't re-assign the value at this index with '=' if I remove the '&'.但是,如果我理解正确的话,如果我删除了“&”,我就不能用“=”重新分配这个索引的值。 The compiler will also throw this error if I do so:如果我这样做,编译器也会抛出这个错误:

error: lvalue required as left operand of assignment错误:需要左值作为赋值的左操作数

What am I supposed to do here?我应该在这里做什么?

The return type of the function should be T& , not int& : function 的返回类型应该是T& ,而不是int&

T& operator [](int offset);

Also note that, while it is nice that you check to make sure the index is in range, you don't actually do anything about it.另请注意,虽然您检查以确保索引在范围内是件好事,但您实际上并没有对此做任何事情。 One solution is to throw an exception:一种解决方案是抛出异常:

#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];
}

If you really want to be consistent with STL containers, let operator[] be unchecked, and add a debug-time check like:如果您真的想与 STL 容器保持一致,请取消选中operator[] ,并添加调试时检查,例如:

#include <cassert>

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

Adding a const-overload of this operator would also be nice:添加此运算符的常量重载也很好:

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

first you should adjust the return type according to your value type:首先你应该根据你的值类型调整返回类型:

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

  return pT[offset];
}

Then if you want it to also work in constant mode add the following overload:然后,如果您希望它也以常量模式工作,请添加以下重载:

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];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM