当前位置: 首页 > 知识库问答 >
问题:

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

云何平
2023-03-14

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

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
    }
};

很好用。

所以,我有一个问题:

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

共有3个答案

王景山
2023-03-14

我想你真的在问为什么标准允许一个而不允许另一个。原因主要与人们的预期有关,而不是某种技术逻辑排除了一种情况下的违约,而不是另一种情况下的违约:

这是人们期望[]操作符是什么意思的问题。通常它的意思是“在[…]获取元素”我们使用int或其他类型对集合的成员进行特定查询。我们总是有兴趣询问某个特定成员的情况,我们心里总是有一个特定的问题。

现在考虑一下默认参数的含义。通常它的意思是“你可以指定这个,但如果没有,我就假设这个默认值”。这对某些功能非常有效,人们已经习惯了。

改变这一点可能会让很多人在看到int x=vec[]时挠头

毕霖
2023-03-14
  • 为什么不允许数组下标运算符的默认参数

主要是因为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 )

大括号的参数是可选的,大括号的参数不是可选的。正如评论中所建议的那样,请注意,括号必须只包含一个参数,而大括号可以包含任意数量的参数。

也可以考虑宋元耀对标准中明确声明的回答。

卢皓轩
2023-03-14

该标准非常清楚地说明了这一点。

在订阅运算符的运算符重载中不允许使用默认参数。

运算符函数不能有默认参数,除非下面明确说明。运算符函数的参数不能大于或小于相应运算符所需的数量,如本款其余部分所述。

操作符[]应该是一个非静态成员函数,只有一个参数。

而对于函数调用操作符

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

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

 类似资料:
  • C++ 重载运算符和重载函数 函数调用运算符 () 可以被重载用于类的对象。当重载 () 时,您不是创造了一种新的调用函数的方式,相反地,这是创建一个可以传递任意数目参数的运算符函数。 下面的实例演示了如何重载函数调用运算符 ()。 #include <iostream> using namespace std; class Distance { private: int

  • 算术运算符以数值(字面量或变量)作为其操作数,并返回一个单个数值。标准算术运算符是加法(+),减法( - ),乘法(*)和除法(/)。—— MDN 算数运算符是用来做算数运算的,如 + 这个符号,就是用来做加法操作。 1. N元运算 N 代表一个数,如一元运算,二元运算。 N元运算 表示由N个值产生一个新的值的规则。 如 * 就是一个二元运算符,他由两个数相乘产生第三个数。 JavaScript

  • 首先,我想问为什么默认三向运算符的行为不同于用户定义运算符? 其次,这个问题的解决方案对于类是正确的,还是应该以不同的方式处理? 这只是一个简单的例子,我想到了更复杂的情况,有几十个字段和联合(如果您不知道我的意思,请查看一些Intel API;))。 我稍微修改了示例中的类,以便更多地描述实际生活中的问题(当默认运算符不是有效的解决方案时)。我还想澄清,我想知道这些差异背后的原因(用户定义和默认

  • C++ 重载运算符和重载函数 下标操作符 [] 通常用于访问数组元素。重载该运算符用于增强操作 C++ 数组的功能。 下面的实例演示了如何重载下标运算符 []。 #include <iostream> using namespace std; const int SIZE = 10; class safearay { private: int arr[SIZE]; pu

  • 问题内容: 从C ++到Java,一个显而易见的未解决问题是Java为什么不包括运算符重载? 没有;比这简单;吗? 是否存在已知的原因,有效的论据,不使运算符重载?原因是任意的还是迷失了时间? 问题答案: 假设你想覆盖所引用的对象的先前值a,则必须调用成员函数。 在C ++中,此表达式告诉编译器在堆栈上创建三(3)个对象,执行加法,然后将结果值从临时对象复制到现有对象中。 但是,在Java中,不对

  • 我有一个模板类包含其他类的优先级队列,我需要使用优先级重载器调用各个类重载器,根据各个类的偏好进行比较(在这种情况下是年龄,在另一个类中可能是价格。 我绝对相信我已经实现了不正确的运算符重载,因此非常感谢您的建议。 举个例子 我得到这个错误,我不知道我需要做什么来修复它。我必须将类重载保持为单个变量(Animal) 任务cpp:在“布尔运算符”的实例化中