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

msc*_*msc 11 c++ operator-overloading operators language-lawyer default-arguments

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

struct st 
{
    int operator[](int x = 0)
    {
        // code here
    }
};
Run Code Online (Sandbox Code Playgroud)

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

error: 'int st::operator[](int)' cannot have default arguments
     int operator[](int x = 0)
Run Code Online (Sandbox Code Playgroud)

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

struct st 
{
    int operator()(int x = 0)
    {
        // code here
    }
};
Run Code Online (Sandbox Code Playgroud)

它工作正常.

所以,我有一个问题:

  • 为什么不允许数组下标运算符的默认参数?
  • 为什么允许函数调用运算符的默认参数?

Jod*_*cus 13

  • 为什么不允许数组下标运算符的默认参数?
  • 为什么允许函数调用运算符的默认参数?

主要是因为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 )
Run Code Online (Sandbox Code Playgroud)

大括号的参数是可选的,括号的参数不是.正如评论中所建议的那样,请注意,括号只需要一个参数,而大括号可以采用任意数量的参数.

还要考虑宋元尧对标准明确陈述的回答.

  • 这个答案很棒.它可以通过注意`[]`必须正好采用1个参数,不多也不少,更清楚地阅读英语来改进. (8认同)

son*_*yao 13

该标准非常明确地说明了这一点

标运算符的运算符重载中不允许使用默认参数.

除非下面明确说明,否则运算符函数不能具有默认参数.运算符函数的参数不能超过相应运算符所需的数量,如本子条款的其余部分所述.

operator[] 应该是一个非静态成员函数,只有一个参数.

而对于函数调用运算符

operator()应该是具有任意数量参数的非静态成员函数.它可以有默认参数.

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

  • 这个答案比我的好.它从标准中给出了一个明确的声明,它总是超出语法规范. (2认同)