C++ 在运算符重载中使用可变模板合法吗?

C++ 在运算符重载中使用可变模板合法吗?,c++,templates,operator-overloading,language-lawyer,variadic-templates,C++,Templates,Operator Overloading,Language Lawyer,Variadic Templates,我希望能够按照以下思路写一些东西: struct bar {}; template <typename ... Args> bar operator+(bar, Args ...) {} structbar{}; 模板 条形运算符+(条形,参数…) {} 我刚刚用clang/gcc进行了检查,重载运算符是通过二进制表达式(a+b)和一元表达式(+a)提取的,正如我所预料的那样。但是,运算符比普通函数更受限制,例如,不能用三个参数重载operator+() 上述使用是否合法且可携

我希望能够按照以下思路写一些东西:

struct bar {};

template <typename ... Args>
bar operator+(bar, Args ...)
{}
structbar{};
模板
条形运算符+(条形,参数…)
{}
我刚刚用clang/gcc进行了检查,重载运算符是通过二进制表达式(
a+b
)和一元表达式(
+a
)提取的,正如我所预料的那样。但是,运算符比普通函数更受限制,例如,不能用三个参数重载
operator+()

上述使用是否合法且可携带


编辑为了给大家一点背景知识,我显然不希望能够定义可变运算符或任何类似的东西。我对此感兴趣的原因是一个丑陋的黑客:我想让一些操作符可变,这样我就可以用其他非可变实现“覆盖”它们。由于在函数模板重载规则中,可变模板被认为不如非可变模板专业,因此我可以用非可变算子覆盖可变算子。是的,这非常可怕:)

首先,定义很好,因为存在具有非空packs1的有效专门化

现在,将特定表达式
a+b
+a
分别转换为
运算符+(a,b)
运算符+(a)
形式的非成员调用()。名称查找然后查找运算符函数模板,其专门化成为候选函数的一部分。最后,只需像往常一样让学员超负荷解决问题:

重载解析的候选函数集是 成员候选、非成员候选和内置 候选人参数列表包含 操作人员候选函数集中的最佳函数为 根据13.3.2和13.3.3选择。

您的代码也将按预期工作,因为重载解析和偏序将像所有其他代码一样尊重操作符函数模板



1除了后缀
--
++
之外,为一元运算符声明上述内容是格式错误的,不需要诊断。Cf..

标准限制运算符函数的参数数量(以及默认参数的存在),具体如下:

8-运算符函数不能有默认参数([dcl.fct.default]),除非下面明确说明。操作人员 函数的参数不能大于或小于相应运算符所需的数量, 如本款其余部分所述

但是,您声明的是运算符函数模板,它没有此类限制。这意味着您的代码很好;一元或二元
++
的使用将转换为使用一个或两个参数调用
运算符+
,并相应地生成模板的适当实例化

如果使用非法数量的参数专门化或显式实例化运算符函数模板,则是非法的,因为([over.oper]):

1-[…]运算符函数模板的特殊化也是运算符 功能。[……]


请注意,如果我们编写一个非可变运算符函数模板,该模板可以用不正确的类型实例化,则会产生类似的效果:

template<class T> int operator+(T, T) { return 0; }  // OK
struct bar {}; template int operator+(bar, bar);     // OK
template int operator+(int, int);                    // Error is here
template int操作符+(T,T){返回0;}//OK
结构条{};模板int运算符+(条形,条形);//好啊
模板int运算符+(int,int);//错误就在这里

谢谢你的回答,我在原来的问题中添加了一些上下文。@Bluescani是的,没问题。