在运算符重载中使用可变参数模板是否合法?

blu*_*rni 10 c++ templates operator-overloading language-lawyer variadic-templates

我希望能够按照以下方式写一些东西:

struct bar {};

template <typename ... Args>
bar operator+(bar, Args ...)
{}
Run Code Online (Sandbox Code Playgroud)

我刚用clang/gcc检查过,重载的运算符被二进制表达式(a+b)和一元表达式(+a)所取代,正如我所料.但是,运算符比正常函数更受限制,例如 - 你不能operator+()用三个参数重载.

以上用法是否合法且便携?

编辑为了给出一些上下文,我显然不希望能够定义可变运算符或任何类型的运算符.我对此感兴趣的原因是一个丑陋的黑客:我想使一些运算符变量,以便我可以用其他非变量实现"覆盖"它们.由于变量模板被认为不如函数模板重载规则中的非可变参数模板专用,我可以使用非可变参数覆盖可变参数运算符.是的,它非常可怕:)

Col*_*mbo 6

首先,定义很好,因为存在非空包1的有效特化.

现在,具体表达式a+b+a变换成形式的非成员的呼叫IA operator+(a, b)operator+(a),分别为([over.match.oper]/2).然后,名称查找会找到运算符函数模板,其专业化将成为候选项的一部分.最后,[over.match.oper]/6像往常一样委托重载解析:

重载决策的候选函数集是成员候选者,非成员候选者和内置候选者的联合.参数列表包含运算符的所有操作数.根据13.3.2和13.3.3选择候选函数集中的最佳函数.

您的代码也将按预期工作,因为重载决策和部分排序将像所有其他人一样尊重操作员功能模板.


1宣告上述一元运算符,也许除了postfix的--++,是形成不良的,没有诊断需要.参看 [temp.res] /(8.2).