我想在cpp中实现python列表,但卡在重载下标运算符[]和逗号,[关闭]
Posted
技术标签:
【中文标题】我想在cpp中实现python列表,但卡在重载下标运算符[]和逗号,[关闭]【英文标题】:I want to implement python list in cpp, but stuck at overloading subscript operator [ ] and comma , [closed] 【发布时间】:2021-07-30 17:42:36 【问题描述】:我想在cpp中实现puthon list,bug没有找到实现pyton的切片操作符的方法,例如:
list[3:7] // sublist including item 3 included to item 7 excluded
由于冒号不是 cpp 中的运算符,我们不能重载它。所以我改变了我的实现以使用可重载的逗号,例如list[3,7]
。我想我首先需要重载逗号运算符,然后重载[ ]
运算符
但是在使用 2 个整数重载 [ ]
时出现错误:
Error is : operator[](int, int) must have exactly one argument
请帮我解决问题。
【问题讨论】:
恐怕您无法获得任何语法。您是正确的,运算符:
不能重载,但是要重载 ,
运算符,您需要一个类对象(或枚举) - 您不能为整数等原始类型提供运算符重载。如果您可以与list(3, 7)
或list[3, 7]
一起生活,则可以这样做。
最接近你想要的就是重载operator()
这并不容易......唯一的选择是在rangev3中使用切片
确实,重复是不合适的:它不是关于二维索引,而是关于slicing,这也很困难,因为可能缺少较低或较高的操作数。
【参考方案1】:
C++ 标准对operator[]
施加了限制:
[over.sub]:
operator[]
应该是一个只有一个参数的非静态成员函数。它实现了下标语法(...) 下标表达式
x[y]
被解释为x.operator[](y)
(...)
但单个参数不必是标量。例如:
struct mylist
vector<int> oops 3,5, 7, 9;
int& operator[] (size_t i)
cout << "indexing overload"<<endl;
return oops[i];
mylist operator[] (pair<int, int>p)
cout << "slicing overload from "<<p.first<<" to "<<p.second<<endl;
return mylist(); // just for proof of concept
;
然后您可以按预期使用此列表:
mylist l;
cout<< l[2] <<endl; // (1) traditional indexing
l[make_pair(3,5)]; // (2) will invoke the slice version
l[4,8]; // (3) slice version as well
Online demo
但是,C++ 不是 python,所以你的代码的读者会对 (2) 和 (3) 的语法感到非常困惑。此外,我不是 python 专家,但我知道slice operator 可能比这更棘手,因为可能存在启动、停止和步进,并且任何这些组件都可能丢失。
所以我建议不要使用一对作为参数,而是创建自己的切片运算符参数。然后,您可以处理不同的构造函数和默认参数。它可能看起来像:
l[myslice(3, 5)]; // myslice is a class
l[myslice(3, 4, 2)];
l[mysliceto(5)]; // mysliceto could be a function returning a myslice
// that is constructed using a default value for start
但是由于这仍然是一个非常不寻常的索引方案,鉴于principle of least astonishment,我强烈建议采用 C++ 常规做法并简单地定义正确的成员函数,例如`
l.slice(3,5);
这将是自记录的,毫无意外,并且易于消化,因为它接近众所周知的 string::substr()
语义
【讨论】:
以上是关于我想在cpp中实现python列表,但卡在重载下标运算符[]和逗号,[关闭]的主要内容,如果未能解决你的问题,请参考以下文章