C++不允许使用多参数运算符[]的根本原因

3

目前,我们只能使用一个参数来重载operator[]

我想知道标准不允许为多个参数重载operator[]的根本原因。

是否有关于在C++17中提出此类建议的计划?


反问:你不能使用operator()的根本原因是什么? - PeterT
@PeterT:我正在寻找多维数组讨论,以便在未来的提案中讨论这种限制的解决方法。因此,我想知道为什么不能考虑将多参数运算符[]作为C++核心修改的基本原因是什么... - Vincent
2个回答

5

这可能可以添加,但不应该添加,因为它会破坏现有的代码。

基本上,多个参数传递给operator[]意味着以下内容将会编译:

struct Foo
{
    int operator[](int a, int b, int c)
    {
        return 0;
    }
}

int main()
{
    Foo foo;
    auto n = foo[1, 2, 3]; // list of parameters
}

然而请考虑以下内容:
int main()
{
    Foo foo;
    std::vector<int> bar(4, 0);
    auto n = foo[1, 2, 3]; // list of parameters
    auto x = bar[1, 2, 3]; // comma operator! returning the 3rd element of bar. valid syntax
}

这意味着,在方括号内使用逗号的表达式可以是参数列表,也可以是逗号运算符的使用。 因此,operator[] 的参数只能有一个有效数字,这意味着以下情况无法解决:
struct Foo
{
    int operator[](int a, int b, int c)
    {
        return 0;
    }
    int operator[](int a)
    {
        return 1;
    }
}

这里无法消除1, 2, 3的歧义。这意味着:如果标准更改以允许此操作,则在调用operator[]时使用逗号运算符的任何代码都将变成编译错误。标准委员会尽力不破坏现有代码(这是一件好事!)引入新功能。在我看来,这将是一个相当激进的变化,因此不太可能实现。
如果您需要多个参数,请使用其他运算符(如Mike建议的operator()),或传递std::tuple或等效物。

2
“永远不要破坏现有的代码”这句话有点过于强硬了。“只有在有充分理由的情况下才能破坏现有的代码”。每个版本中都存在无数的破坏性变化:而且在未来,几乎每次对接口进行修改都会在理论上产生破坏性影响,因为我们可以编写条件代码,其行为取决于某些表达式是否不能编译。 - Yakk - Adam Nevraumont
据我所知,他们尽力避免破坏事物。当然,如果例如添加了新关键字,这可能会破坏某些东西,但他们肯定不会对逗号运算符进行如此激进的更改。我略微修改了我的表述方式。 - stefan

5
我想知道标准为什么不允许对多个参数重载operator[],这是否有根本原因?
没有根本原因;只是重载的运算符必须与内置运算符具有相同的语法原则。
C++17中是否有类似的提案?
没有。一个常见的替代方法是重载operator();它可以接受任意数量的参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接