C++ 运算符 [] 重载没有响应
C++ operator [] overload not responding
我已经创建了 class 数组,但有些东西变得很奇怪。class 如下:
class array
{
private:
int *a_;
size_t size_;
public:
array();
array(const size_t);
array(const arreglo &);
~array();
int const &operator[](size_t)const;
int &operator[](size_t);
array const &operator=(const array&);
bool empty()const;
};
[] 的重载实现是:
int const &array::operator[](size_t index)const
{
std::cout << "getter" << std::endl;
return a_[index];
}
int & array::operator[](size_t index)
{
std::cout << "setter" << std::endl;
return a_[index];
}
我测试代码的方式主要是:
int main()
{
array a(7);
a[0] = 3;
a[1] = 6;
a[2] = a[0] + a[1];
array b = a;
std::cout << b[2] << std::endl;
return 0;
}
问题是 opertar [] 仅使用 getter 版本并通过 cout "setter" 打印,而不是 "getter"。
出了什么问题?
简而言之
void f(const array& b){
std::cout << b[2] << std::endl;
}
b 必须是常量。所有可用的是 const 函数。
在你的例子中它是一个 "read" 但是 b 不是 const 所以调用非常量。它使用 "setter" 作为 getter。
将它们视为 "getter" 和 "setter" 变体是错误的。两者之间的区别仅仅是函数的 cv 限定和 return 类型。他们都是吸气剂。更重要的是,您正在 returning 引用类型。
引用往往会衰减,在本例中为可变 int,因此编译器更有可能接受非常量函数调用。
a[0];
此语句的默认评估是一个整数值,而不是一个引用,因此您可以执行以下操作:
if (a[0])
这是基于 a[0] 处的值而不是引用(评估引用总是正确的并且不是很有帮助)。
请记住,当在大多数语句中使用引用时,它们会衰减为引用值。
int v = a[0]; // no error, even tho v's type is not int&
int& vr = a[0]; // decays to the value a references
// then takes a reference of that
(注意:编译器可能会省略隐含的操作集,以简单地捕获或隐含第二个语句中的原始引用)。
所以代码
a[2] = a[0] + a[1]
它首先从 a[0] 和 a[1] 获取值,知道它要进行数学运算,因此最简单的方法是:
int a1 = a.operator[](1);
int a0 = a.operator[](0);
int& dest = a.operator[](2);
dest = a0 + a1;
如果你想要 const,你将需要一个 const/const-ref 到一个数组或者指定你想要一个 const ref:
const int& ar = a[0];
#include <iostream>
struct array
{
int i = 0;
array() {}
const int &operator[](size_t) const { std::cout << "const int[]\n"; return i; }
int &operator[](size_t) { std::cout << "int[]\n"; return i; }
};
int main()
{
array a;
a[0];
int v1 = a[0];
const int v2 = a[0];
std::cout << "refs\n";
int& v3 = a[0];
const int& v4 = a[0];
std::cout << "const array\n";
const array b;
b[0];
int v5 = b[0];
const int v6 = b[0];
std::cout << "refs\n";
//int& v7 = b[0]; // would produce a compile error
const int& v8 = b[0];
}
我已经创建了 class 数组,但有些东西变得很奇怪。class 如下:
class array
{
private:
int *a_;
size_t size_;
public:
array();
array(const size_t);
array(const arreglo &);
~array();
int const &operator[](size_t)const;
int &operator[](size_t);
array const &operator=(const array&);
bool empty()const;
};
[] 的重载实现是:
int const &array::operator[](size_t index)const
{
std::cout << "getter" << std::endl;
return a_[index];
}
int & array::operator[](size_t index)
{
std::cout << "setter" << std::endl;
return a_[index];
}
我测试代码的方式主要是:
int main()
{
array a(7);
a[0] = 3;
a[1] = 6;
a[2] = a[0] + a[1];
array b = a;
std::cout << b[2] << std::endl;
return 0;
}
问题是 opertar [] 仅使用 getter 版本并通过 cout "setter" 打印,而不是 "getter"。 出了什么问题?
简而言之
void f(const array& b){
std::cout << b[2] << std::endl;
}
b 必须是常量。所有可用的是 const 函数。
在你的例子中它是一个 "read" 但是 b 不是 const 所以调用非常量。它使用 "setter" 作为 getter。
将它们视为 "getter" 和 "setter" 变体是错误的。两者之间的区别仅仅是函数的 cv 限定和 return 类型。他们都是吸气剂。更重要的是,您正在 returning 引用类型。
引用往往会衰减,在本例中为可变 int,因此编译器更有可能接受非常量函数调用。
a[0];
此语句的默认评估是一个整数值,而不是一个引用,因此您可以执行以下操作:
if (a[0])
这是基于 a[0] 处的值而不是引用(评估引用总是正确的并且不是很有帮助)。
请记住,当在大多数语句中使用引用时,它们会衰减为引用值。
int v = a[0]; // no error, even tho v's type is not int&
int& vr = a[0]; // decays to the value a references
// then takes a reference of that
(注意:编译器可能会省略隐含的操作集,以简单地捕获或隐含第二个语句中的原始引用)。
所以代码
a[2] = a[0] + a[1]
它首先从 a[0] 和 a[1] 获取值,知道它要进行数学运算,因此最简单的方法是:
int a1 = a.operator[](1);
int a0 = a.operator[](0);
int& dest = a.operator[](2);
dest = a0 + a1;
如果你想要 const,你将需要一个 const/const-ref 到一个数组或者指定你想要一个 const ref:
const int& ar = a[0];
#include <iostream>
struct array
{
int i = 0;
array() {}
const int &operator[](size_t) const { std::cout << "const int[]\n"; return i; }
int &operator[](size_t) { std::cout << "int[]\n"; return i; }
};
int main()
{
array a;
a[0];
int v1 = a[0];
const int v2 = a[0];
std::cout << "refs\n";
int& v3 = a[0];
const int& v4 = a[0];
std::cout << "const array\n";
const array b;
b[0];
int v5 = b[0];
const int v6 = b[0];
std::cout << "refs\n";
//int& v7 = b[0]; // would produce a compile error
const int& v8 = b[0];
}