为什么C++运算符重载需要"having at least one parameter of class type"?
why C++ operator overloading requires "having at least one parameter of class type"?
《c++入门第5版》第14.1章如下:
操作符函数必须是类的成员,或者至少有一个类类型的形参。
例如,string("hello")+"world"
编译"hello"+"world"
不编译。当我想在两个C字符串上重载+
时。
std::string operator+ (const char* s1, const char* s2)
我得到以下错误。
错误:' std::string operator+(const char*, const char*) '必须有一个类或枚举类型的参数
我有两个问题
这个限制是语言规范的一部分吗?如果是,为什么c++设计者要这样做?
std::string
具有类似string (const char* s);
的构造函数,这意味着编译器可以隐式地从char*
到string
进行类类型转换。当我们调用"hello"+"world"
, 时,为什么编译器不将两个char*
' s转换为两个字符串?毕竟,在两个std::字符串上有一个重载的"+"。string operator+ (const string& lhs, const string& rhs);
- 这个限制是语言规范的一部分吗?
是的,它是。为什么?嗯,主要原因可能是因为重新定义标准类型的常用操作符被视为混淆。想象重载operator+(int,int)
或operator+(int,char*)
。这将改变现有代码的含义!
你可以争辩说,在标准类型之间有没有定义的操作符,所以你可以安全地覆盖它们,例如operator*(char*,int)
,但这通常被认为是相当无用的。
此外,操作符重载必须是全局的(或者在其某些成员的名称空间中(参数依赖查找),但对于标准类型,没有可依赖的名称空间),因此想要覆盖它们的库之间的互操作性将是一场噩梦。
"hello" + "world"
:为什么编译器不将两个char* ' s转换为两个字符串?
好吧,首先,std::operator+(const std::string&, const std::string&)
在namespace std;
中,所以默认情况下不会找到它。
你可以尝试显式调用操作符:std::operator+("hello", "world")
,但是,唉,有太多的operator+()
重载,其中许多是模板,调用是二义性的。
因此,考虑到所有这些,我认为合理的要求是至少有一个操作符是用户定义的类型。想想看:全局和命名空间问题得到解决,可以使用ADL(实际上它是为此用途而发明的),并且不可能重新定义具有现有含义的操作符(除了operator,()
和operator&()
,我认为,但是谁想要覆盖这些…)。
正如Bjarne在Design and Evolution中所说,我们的目标是使扩展语言变得容易,而不是改变语言。如果您只允许重载内置类型,那么您将改变语言,并且允许这样做违背了设计目标。(例如,它会鼓励形成互不相容的方言,从而使社区破裂。)
这个限制是语言规范的一部分吗?如果是的话,为什么c++设计者要这样做呢?
是的,它是。引用自N3337,§13.5.6 [over.oper]:
操作符函数要么是非静态成员函数,要么是非成员函数,并且至少有一个形参的类型是类、类的引用、枚举或枚举的引用。
关于"为什么"的部分,因为删除这个要求意味着你可以重载内置类型的操作符,这些内置类型已经定义了它们的操作符语义。这是完全不可取的。
例如,你认为定义这个有意义吗?
int operator+(int a, int b) { return a - b; }
它是否允许更多的人在阅读你的代码时对你的程序进行推理,或者它只是一些令人惊讶的东西,有效地破坏了你的推理?
如果我们在游戏中加入指针会发生什么?
bool operator==(const char *str1, const char *str2) {
return strcmp(str1, str2) == 0;
}
你期望operator==
现在解引用内存吗?我不会。这是令人惊讶的。这违背了标准对这些运营商的规定。它打破了过去25年里所有C程序的行为。语言不应该让你做这种滥用。
- 修复"-Wunused-parameter"取决于预处理器条件的警告
- C++模板错误:"invalid explicitly-specified argument for template parameter"
- 为什么"types may not be defined in parameter types"
- 如何理解"abstract-declarator containing an ellipsis shall only be used in a parameter-declaration"
- QT C++如何调用lambda one
- 为什么'allocate in one library and free in the other'是错误的
- 为什么这段代码抱怨"a non-type template parameter cannot have type"?
- 如何抛出"template parameter"类型的异常?
- 如何在开关语句中使用 cin "as a parameter"
- 派生类中函数参数变化的虚函数按常量类型在"function parameter"会破坏虚拟机制吗?
- 在 lambda(parameter) 中为 std::transform with std::sregex_token
- 如何修复此"argument of type incompatible with parameter"错误?
- 谷歌模拟 - 怎么说"function must be called ONCE with a certain parameter but ok to be called many times with
- C++ WinRT - XAudio2是否支持Xbox One平台
- CUDA 内核"Only a single pack parameter is allowed"解决方法?
- "Cannot convert parameter 1 from double to float"虽然没有更改参数
- 为什么我收到错误:"there is more than one default constructor"?
- rvalue for a std::string parameter
- g++ 在我尝试用 ONE LINE 编译程序时崩溃了
- 为什么C++运算符重载需要"having at least one parameter of class type"?