为下标运算符和函数调用运算符提供默认参数

Provide default arguments for subscript operator and function call operator

在下面的代码中,我为数组下标运算符提供了默认参数

struct st 
{
    int operator[](int x = 0)
    {
        // code here
    }
};

但是,编译器产生了一个错误:

error: 'int st::operator[](int)' cannot have default arguments
     int operator[](int x = 0)

但是,如果我为 函数调用 运算符提供默认参数。

struct st 
{
    int operator()(int x = 0)
    {
        // code here
    }
};

一切正常。

所以,我有一个问题:

  • Why doesn't allowed default argument for array subscript operator?
  • Why does allowed default argument for function call operator?

主要是因为C++语法是这么说的。根据 A.4 [gram.expr]:

postfix-expression --> postfix-expression [ expr-or-braced-init-list ] 
                   --> postfix-expression ( expression-list opt ) 
                   --> simple-type-specifier (expression-list opt) 
                   --> typename-specifier ( expression-list opt )

花括号的参数是可选的,括号的参数不是。 正如评论中所建议的那样,请注意,括号需要恰好采用 one 参数,而大括号可以采用任意数量的参数。

同时考虑一下 songyuanyao 的回答,以获得标准中的明确声明。

标准说的很清楚。

operator overloading of subscripting operator 中不允许使用默认参数。

An operator function cannot have default arguments, except where explicitly stated below. Operator functions cannot have more or fewer parameters than the number required for the corresponding operator, as described in the rest of this subclause.

operator[] shall be a non-static member function with exactly one parameter.

同时 function call operator

operator() shall be a non-static member function with an arbitrary number of parameters. It can have default arguments.

重载运算符试图遵循与内置运算符相同的行为;对于内置的下标运算符,始终需要(只有一个)索引,它没有 默认参数 。然后重载运算符也不允许有默认参数。另一方面,函数总是可以接受任意数量的参数并具有默认参数。

运算符(用户定义类型和内置类型的重载)旨在让人们使用数学、逻辑和一般用法中熟悉的符号(尽管 <<>>被视为流媒体运营商的双重服务,鉴于计算机上几乎普遍可用的有限字符,必须做出符号妥协)。转而允许对直观、熟悉的符号(例如隐含参数)进行变体似乎适得其反。

operator() 的不同之处在于它可以抽象出 "calling"(通过)对象和调用硬编码函数之间的差异 - 它需要支持默认参数才能正确执行此操作.

我想你真的在问为什么标准允许一个而不是另一个。 原因主要是为了满足人们的期望,而不是一些技术逻辑在一种情况下排除默认值而在另一种情况下排除默认值:

这取决于人们期望 [] 运算符的含义。通常它表示 "Get the element at [...]" ,我们使用 int 或其他类型来对集合的成员进行特定查询。我们总是有兴趣询问特定成员,并且我们总是有一个特定的查询。

现在考虑默认参数的含义。通常它意味着 "you can specify this, but if not I'll assume this default"。这对某些功能非常有效,人们已经习惯了。

改这个估计会让很多人看到都挠头int x = vec[]