复制构造函数作为模板化成员函数被忽略

Ale*_*eev 1 c++ templates

是否可以将赋值运算符推导为成员函数模板的特例?

例如,我有一个带有一个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;
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码片段中,clang和gcc编译的二进制文件不打印任何关于赋值 - 据我所知,默认赋值在这里生成,尽管可以从模板中推导出它.

Bar*_*rry 6

他们不打印任何东西是正确的.发生的事情是为此签名创建了一个隐式复制赋值运算符A<true>:

A<true>& operator=(const A<true>& );
Run Code Online (Sandbox Code Playgroud)

因此,当我们进行重载决策时,有两个可行的候选者:

A<true>& operator=(const A<true>& );     // implicit copy assignment
A<true>& operator=(const A<input_sw>& ); // [ with input_sw = true ]
Run Code Online (Sandbox Code Playgroud)

两个运算符都采用相同的参数(const A<true>&),因此从这个角度看它们是等同的好候选者.但非模板函数比函数模板特化更受欢迎,这使得隐式复制赋值运算符成为最佳可行候选者.


现在,考虑一个替代方案.如果以这种方式声明运算符模板,该怎么办

template<bool input_sw>
A & operator =(A<input_sw> &a) { ... }
Run Code Online (Sandbox Code Playgroud)

那不是const.这不是一个好的做法,我只是为了说明目的而提出这个.在这种情况下,我们的两个候选人a=b是:

A<true>& operator=(const A<true>& );   // implicit copy assignment
A<true>& operator=(A<input_sw>& );     // [ with input_sw = true ]
Run Code Online (Sandbox Code Playgroud)

现在这两位候选人没有采取相同的论点.我们的运营商模板引用了非const.在两个引用的情况下,引用最后一个cv -qualified类型的引用是优选的,在这种情况下它将是运算符.删除它const,现在你的功能是首选,你会看到打印的东西.

C++是最好的.