why assigment operator can not be frined

在尝试将一个结构体赋值给字符串时遇到问题,原本期望通过重载赋值运算符来解决,但编译报错。原因是C++中不允许将赋值运算符声明为独立的非成员函数,以防翻译单元中行为发生变化,导致不一致。解决方案是直接覆盖原有函数,并在需要的地方调用相应版本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

博客搬家,原地址:https://langzi989.github.io/2017/03/21/why-assigment-operator-can-not-be-frined-function/

this is a problem in my work and I have find th solution on stackoverflow,so recorder here

problem description

When I refactor my object, I have a problem which need to change the return value
of and function std::string to a struct data, but I don’t want to change my code
where the function be used, so I want to overload the assignment operator which
will assign a struct to string.The code is as follows:

#include <string>
class data_struct{
  friend std::string operator = (std::string& s, data_struct& d);
private:
  bool success{false};
  std::string message{""};
public:
  data_struct(bool t_success, std::string t_message):
            success(t_success), message(t_message) {}
}

std::string operator = (std::string& s, data_struct& d) {
  s = d.s;
  return s;
}

int main() {
  data_struct d(false,"haha");
  std::string s = d;
}

when I compile this file , this is an error follows:

main.cpp:3:64: error: ‘std::__cxx11::string operator=(std::__cxx11::string&, data_struct&)’ must be a nonstatic member function
   friend std::string operator = (std::string& s, data_struct& d);
                                                                ^
main.cpp:12:13: error: expected initializer before ‘operator’
 std::string operator = (std::string& s, data_struct& d) {
             ^
main.cpp: In function ‘int main()’:
main.cpp:19:19: error: conversion from ‘data_struct’ to non-scalar type ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ requested
   std::string s = d;

why does this happen?

Firstly, it should be noted that this has nothing to do with the operator being implemented as a friend specifically. It is really about implementing the copy-assignment as a member function or as a non-member (standalone) function. Whether that standalone function is going to be a friend or not is completely irrelevant: it might be, it might not be, depending on what it wants to access inside the class.

Now, the answer to this question is given in D&E book (The Design and Evolution of C++). The reason for this is that the compiler always declares/defines a member copy-assignment operator for the class (if you don’t declare your own member copy-assignment operator).

If the language also allowed declaring copy-assignment operator as a standalone (non-member) function, you could end up with the following

// Class definition
class SomeClass {
  // No copy-assignment operator declared here
  // so the compiler declares its own implicitly
  ...
};

SomeClass a, b;

void foo() {
  a = b;
  // The code here will use the compiler-declared copy-assignment for `SomeClass`
  // because it doesn't know anything about any other copy-assignment operators
}

// Your standalone assignment operator
SomeClass& operator =(SomeClass& lhs, const SomeClass& rhs);

void bar() {
  a = b;
  // The code here will use your standalone copy-assigment for `SomeClass`
  // and not the compiler-declared one
}

As seen in the above example, the semantics of the copy-assignment would change in the middle of the translation unit - before the declaration of your standalone operator the compiler’s version is used. After the declaration your version is used. The behavior of the program will change depending on where you put the declaration of your standalone copy-assignment operator.

This was considered unacceptably dangerous (and it is), so C++ doesn’t allow copy-assignment operator to be declared as a standalone function.

It is true that in your particular example, which happens to use a friend function specifically, the operator is declared very early, inside the class definition (since that’s how friends are declared). So, in your case the compiler will, of course, know about the existence of your operator right away. However, from the point of view of C++ language the general issue is not related to friend functions in any way. From the point of view of C++ language it is about member functions vs. non-member functions, and non-member overloading of copy-assignment is just prohibited entirely for the reasons described above.

Solution

due to the solution above is not proper.So I overWrite the orignal function, and
invoke different version in their needed place.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值