是否可以将赋值运算符推导为成员函数模板的特例?
例如,我有一个带有一个bool参数的类模板,并且想要实现assign操作,而不管模板参数的任何特定值。
#include <iostream>
template<bool sw>
struct A {
A() {
std::cout << __PRETTY_FUNCTION__ << '\n';
}
template<bool input_sw>
A & operator = (const A<input_sw> &a) {
std::cout << __PRETTY_FUNCTION__ << '\n';
return *this;
}
};
int main()
{
A<true> a;
A<true> b;
a = b;
}
在上面的代码片段中,clang和gcc编译的二进制文件不打印任何关于赋值的内容 - 据我所知,默认赋值在这里生成,尽管可以从模板中推断出它。
答案 0 :(得分:6)
他们不打印任何东西是正确的。发生的事情是,为A<true>
创建了一个带有此签名的隐式复制赋值运算符:
A<true>& operator=(const A<true>& );
因此,当我们进行重载决策时,有两个可行的候选者:
A<true>& operator=(const A<true>& ); // implicit copy assignment
A<true>& operator=(const A<input_sw>& ); // [ with input_sw = true ]
两个运算符都采用相同的参数(const A<true>&
),因此从这个角度看它们是等同的好候选者。但非模板函数比函数模板特化更受欢迎,这使得隐式复制赋值运算符成为最佳可行候选者。
现在,考虑另一种选择。如果您以这种方式声明操作员模板,该怎么办:
template<bool input_sw>
A & operator =(A<input_sw> &a) { ... }
即,不是const
。这不是一种好的做法,我只是为了说明目的而提出这一做法。在这种情况下,a=b
的两位候选人是:
A<true>& operator=(const A<true>& ); // implicit copy assignment
A<true>& operator=(A<input_sw>& ); // [ with input_sw = true ]
现在两个候选人不采取相同的论点。我们的运算符模板引用了非const
。在两个引用的情况下,引用最后一个 cv - 限定类型的引用是优选的,在这种情况下它将是运算符。删除const
,现在您的功能是首选,您将看到打印的内容。
C ++是最好的。