C++ 语法允许在结构/类中定义重载运算符,例如:
struct X
{
void operator+(X);
}
或在结构/类之外,例如:
void operator+(X, X);
但不是:
struct X
{
static void operator+(X, X);
}
有人知道这个决定的原因吗?为什么不允许使用第三种形式? (MSVC 给出了一个语法错误。)也许这背后有一些故事?
附:第一个和第二个定义同时存在会造成歧义:
1>CppTest1.cxx
1>c:\ballerup\misc\cf_html\cpptest1.cxx(39) : error C2593: 'operator +' is ambiguous
1> c:\ballerup\misc\cf_html\cpptest1.cxx(13): could be 'void B1::operator +(B1 &)'
1> c:\ballerup\misc\cf_html\cpptest1.cxx(16): or 'void operator +(B1 &,B1 &)'
1> while trying to match the argument list '(B1, B1)'
我不明白为什么这种歧义比 1,3 或 2,3 之间更好。
最佳答案
我没有任何关于这个概念的 C++ 讨论的具体知识,所以请随意忽略。
但对我来说,你的问题倒过来了。问题应该是,“为什么这种语法会被允许?”
与当前语法相比,它根本没有任何优势。非静态成员函数版本对私有(private)成员的访问权限与您建议的静态版本相同。因此,如果您需要访问私有(private)来实现它,只需将其设为非静态成员,就像您通常对类的大多数成员所做的那样。
它不会更容易实现非对称运算符(即:operator+(const X &x, const Y &y)
)。如果您需要私有(private)访问来实现这一点,您仍然需要在其中一个类中为它们声明一个 friend 。
所以我会说它不存在的原因是它不是必要的。在非成员函数和非静态成员之间,涵盖了所有必要的用例。
或者,换一种说法:
自由函数可以做静态函数系统可以做的所有事情,还有更多。
通过使用自由函数,您可以对模板中使用的运算符进行依赖于参数的查找。您不能使用静态函数来做到这一点,因为它们必须是特定类的成员。并且您不能从类外部添加 到类,而可以添加到命名空间。因此,如果您需要将运算符放在特定的命名空间中以使某些 ADL 代码工作,您可以。静态函数运算符无法做到这一点。
因此,自由函数是您提议的静态函数系统将提供的所有内容的超集。由于允许它没有任何好处,因此没有理由允许它,因此它是不允许的。
which would make possible to use functors without instantiating them?
这在术语上是矛盾的。 “仿函数”是“函数对象”。类型是不是对象;因此,它不能是仿函数。它可以是一种在实例化时会产生仿函数的类型。但单独的类型不会是仿函数。
此外,能够声明 Typename::operator()
静态并不意味着 Typename()
会做你想做的事。该语法已经具有实际意义:通过调用默认构造函数来临时实例化 Typename
。
最后,即使所有这些不是,那又有什么好处呢?大多数采用某种类型的可调用对象的模板函数与函数指针和仿函数一样工作。你为什么要限制你的接口(interface),不仅仅是仿函数,而是不能有内部数据的仿函数?这意味着您将无法通过捕获 lambda 等。
不可能包含状态的仿函数有什么用?为什么要强制用户传递没有状态的“仿函数”?为什么要阻止用户使用 lambda?
所以你的问题源于一个错误的假设:即使我们有它,它也不会给你你想要的。
关于c++ - 为什么不能将重载的运算符定义为类的静态成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11894124/