【问题标题】:Calling primitive operator-functions explicitly in C++在 C++ 中显式调用原始运算符函数
【发布时间】:2011-05-02 22:45:34
【问题描述】:
int a, b, c; 

//do stuff. For e.g., cin >> b >> c; 

c = a + b;          //works 
c = operator+(a,b); //fails to compile, 'operator+' not defined. 

另一方面,这有效 -

class Foo
{
 int x; 
public:
 Foo(int x):x(x) {} 

 Foo friend operator+(const Foo& f, const Foo& g)
 {
  return Foo(f.x + g.x); 
 }

};    

Foo l(5), m(10); 

Foo n = operator+(l,m); //compiles ok! 
  • 甚至可以直接调用基本类型(如 int)的 operator+(和其他运算符)吗?
  • 如果是,怎么做?
  • 如果没有,是否有 C++ 参考措辞明确表明这是不可行的?

【问题讨论】:

  • 我很好奇,你为什么要这样做?
  • 我正在尝试帮助某人学习 C++,我说的是运算符的行为类似于函数的想法。我想展示一段名为 operator+(2,3) 而不是 2+3 的代码来说明这个想法,因为我意识到它并没有像我预期的那样工作。

标签: c++ function operator-keyword


【解决方案1】:

首先,将内置运算符作为函数调用是行不通的,因为语言规范从来没有说过这样的函数存在。内置运算符只是运算符。它们背后没有实现功能,仅仅是因为语言规范从未暗示它们的存在。基于函数的实现仅特定于 重载 运算符。

其次,在重载决议期间,内置运算符确实由其虚构的类似函数的对应物表示,但禁止“显式”类似函数调用内置运算符的措辞出现在 13.6/1 中

候选运算符函数 表示内置运算符 第 5 条中的定义在 本条。这些候选人 函数参与算子 重载解决过程为 在 13.3.1.2 中描述并使用 无其他目的

【讨论】:

  • 正是我想要的。谢谢!
【解决方案2】:

来自http://www.parashift.com/c++-faq-lite/intrinsic-types.html

我可以定义一个适用于内置/内在/原始类型的运算符重载吗?

不,C++ 语言要求 您的运算符重载至少需要 “类类型”的一个操作数或 枚举类型。 C++ 语言 不会让你定义一个运算符 所有的操作数/参数都是 原始类型。

例如,您不能定义一个 operator== 需要两个 char*s 和 使用字符串比较。那挺好的 新闻,因为如果 s1 和 s2 是类型 char*,表达式 s1 == s2 已经 有一个明确的含义:它 比较两个指针,而不是两个 这些指针指向的字符串。 无论如何,您都不应该使用指针。采用 std::string 而不是 char*。

如果C++让你重新定义了 内置类型的运算符,你 永远不会知道 1 + 1 是什么:它 将取决于获得了哪些标题 包括以及是否其中之一 标题重新定义了除了意思之外, 比如减法。

C++ 标准§13.5.6

操作符函数要么是非静态成员函数,要么是非成员函数,并且至少有一个类型为类、类引用、枚举或枚举引用的参数。无法更改运算符的优先级、分组或操作数的数量。为每种类型预定义的运算符 =、(一元)& 和 ,(逗号)的含义可以通过定义实现这些运算符的运算符函数来针对特定的类和枚举类型进行更改。运算符函数的继承方式与其他基类函数相同。

【讨论】:

  • 我明白这一点。我不想重载原始运算符。我只是试图通过调用它的函数运算符名称来调用原始运算符。
  • @Vatsan: An operator function shall either be a non-static member function or be a non-member function and have at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration. - 这是一个非常明确的要求。
  • 很明显,我被禁止声明不符合这些要求的新操作符函数。它没有告诉我为什么我不能使用运算符函数语法来调用原始运算符,它恰好作为语言的一部分存在。
  • @Vatsan:我不认为它存在,除非你明确声明它,你不能为非类类型声明它。
  • 这是有道理的。我暗暗希望标准中有一些要求,即只禁止重新定义原始运算符,但调用语法对所有这些都被视为相同,因为它无论如何只是语法糖,不会对任何事情产生明显影响但可读性。谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-01-27
  • 2020-05-12
  • 1970-01-01
  • 2011-02-23
  • 1970-01-01
  • 2013-02-06
  • 2016-11-21
  • 2015-05-08
相关资源
最近更新 更多