为什么你不能超载“.” C++ 中的运算符?

发布于 2024-07-13 10:29:33 字数 149 浏览 6 评论 0原文

能够重载 . C++ 中的运算符并返回对对象的引用。

您可以重载 operator->operator*,但不能重载 operator。

这有技术原因吗?

It would be very useful to be able to overload the . operator in C++ and return a reference to an object.

You can overload operator-> and operator* but not operator.

Is there a technical reason for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

瘫痪情歌 2024-07-20 10:29:33

请参阅Bjarne Stroustrup 的这句话

操作员。 (点)原则上可以使用相同的重载
用于->的技术。 然而,这样做可能会引起问题
关于某个操作是否适用于对象重载。 或一个
所引用的对象。 例如:

Y 类 { 
  民众: 
      无效 f(); 
      // ... 
  }; 

  class X { // 假设您可以重载 . 
      Y*p; 
      Y&   运算符。() { 返回*p;   } 
      无效 f(); 
      // ... 
  }; 

  无效g(X&x) 
  { 
      xf();   // X::f 或 Y::f 还是错误? 
  } 
  

这个问题可以通过多种方式解决。 在那个时间
标准化,目前尚不清楚哪种方式最好。 了解更多
详细信息,请参阅C++ 的设计和演变

See this quote from Bjarne Stroustrup:

Operator . (dot) could in principle be overloaded using the same
technique as used for ->. However, doing so can lead to questions
about whether an operation is meant for the object overloading . or an
object referred to by . For example:

class Y {
public:
    void f();
    // ...
};

class X {    // assume that you can overload .
    Y* p;
    Y& operator.() { return *p; }
    void f();
    // ...
};

void g(X& x)
{
    x.f();    // X::f or Y::f or error?
}

This problem can be solved in several ways. At the time of
standardization, it was not obvious which way would be best. For more
details, see The Design and Evolution of C++.

不交电费瞎发啥光 2024-07-20 10:29:33

Stroustrup 说 C++ 应该是一种可扩展的、但不是可变的语言。

点(属性访问)运算符被认为距离语言核心太近,不允许重载。

请参阅C++ 的设计和演变,第 242 页,11.5.2 智能参考部分。

当我决定允许重载运算符 -> 时,我自然会考虑运算符 . 是否可以类似地重载。

当时,我认为以下论点是结论性的:如果 obj 是一个类对象,那么 obj.m 对每个成员 m 都有含义该对象的类的代码>。 我们尽量不通过重新定义内置操作来使语言可变(尽管出于迫切需要,= 和一元 & 违反了该规则)。 p>

如果我们允许类 X 重载 .,我们将无法通过正常方式访问 X 的成员; 我们必须使用指针和 ->,但是 ->& 也可能已被重新定义。 我想要一种可扩展的语言,而不是可变的语言。

这些论点很有分量,但不是结论性的。 特别是,在 1990 年,Jim Adcock 提议允许重载运算符 完全 运算符 -> 的方式。

这句话中的“我”是 Bjarne Stroustrup。 你没有比这更权威的了。

如果你想真正理解 C++(如“为什么会这样”),你绝对应该阅读这本书。

Stroustrup said C++ should be an extensible, but not mutable language.

The dot (attribute access) operator was seen as too close to the core of the language to allow overloading.

See The Design and Evolution of C++, page 242, section 11.5.2 Smart References.

When I decided to allow overloading of operator ->, I naturally considered whether operator . could be similarly overloaded.

At the time, I considered the following arguments conclusive: If obj is a class object then obj.m has a meaning for every member m of that object's class. We try not to make the language mutable by redefining built-in operations (though that rule is violated for = out of dire need, and for unary &).

If we allowed overloading of . for a class X, we would be unable to access members of X by normal means; we would have to use a pointer and ->, but -> and & might also have been re-defined. I wanted an extensible language, not a mutable one.

These arguments are weighty, but not conclusive. In particular, in 1990 Jim Adcock proposed to allow overloading of operator . exactly the way operator -> is.

The "I" in this quote is Bjarne Stroustrup. You cannot be more authoritative than that.

If you want to really understand C++ (as in "why is it this way"), you should absolutely read this book.

不乱于心 2024-07-20 10:29:33

Stroustrup 对此问题有答案

操作员。 (点)原则上可以是
使用与以下相同的技术进行重载
用于->。 然而,这样做可以
引发关于是否
操作是针对对象的
超载。 或引用的对象
经过 。 例如:

Y 类 { 
  民众: 
      无效 f(); 
      // ... 
  }; 
  class X { // 假设您可以重载 . 
      Y*p; 
      Y&   运算符。() { 返回*p;   } 
      无效 f(); 
      // ... 
  }; 
  无效g(X&x) 
  { 
      xf();   // X::f 或 Y::f 还是错误? 
  } 
  

这个问题可以通过多种方式解决
方法。 在标准化的时候,
不清楚哪条路会是
最好的。 有关更多详细信息,请参阅D&E

Stroustrup has an answer for this question:

Operator . (dot) could in principle be
overloaded using the same technique as
used for ->. However, doing so can
lead to questions about whether an
operation is meant for the object
overloading . or an object referred to
by . For example:

class Y {
public:
    void f();
    // ...
};
class X {   // assume that you can overload .
    Y* p;
    Y& operator.() { return *p; }
    void f();
    // ...
};
void g(X& x)
{
    x.f();  // X::f or Y::f or error?
}

This problem can be solved in several
ways. At the time of standardization,
it was not obvious which way would be
best. For more details, see D&E.

狼性发作 2024-07-20 10:29:33

很容易理解,如果你了解一下运算符函数调用的内部机制,
假设一个类复形可以有两个成员 r 代表实部, i 代表虚部。
Complex C1(10,20),C2(10,2) // 我们假设类中已经有一个两个参数的构造函数。
现在,如果您将 C1+C2 编写为语句,则编译器会尝试在复数上查找 + 运算符的重载版本。 现在我们假设我重载了 + 运算符,所以
C1+C2 内部翻译为 c1.operator+(c2)
现在暂时假设您可以重载 '.' 操作员。
所以现在考虑以下调用 C1.disp()//显示复杂对象的内容 现在尝试表示为内部表示
C1.operator.(------) ,创建了完全混乱的东西。 这就是为什么我们不能重载 '.' 的原因。 操作员

It is very easy to understand, if you go through the internal mechanism of operator function invocation,
Say a class complex can have two member r for real part and i for imaginary part.
Say Complex C1(10,20),C2(10,2) // we assume there is an already a two argument constructor within class.
Now if you write C1+C2 as a statement then compiler try to find the overloaded version of + operator on complex number. Now we assume that I overload + operator, so
C1+C2 internally translated as c1.operator+(c2)
Now assume for the time beings you can overload '.' operator.
so now think following call C1.disp()//display content of a complex object Now try to represent as an internal representation
C1.operator.(------) , completely messy things created. That is the reason why we can't overload '.' operator

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文