模板赋值运算符不替换默认赋值运算符

InQ*_*ive 12 c++ templates

C++模板中完整指南第5.3节"成员模板":

请注意,模板赋值运算符不会替换默认赋值运算符.对于相同类型堆栈的分配,仍会调用默认赋值运算符.

这是正确的,因为当我在代码下面运行时:

#include<iostream>
using namespace std;

template<typename T>
class Pair
{
    public:
            T pair1,pair2;
            Pair(T i,T j):pair1(i),pair2(j){}
            template<typename T1>Pair<T>& operator=(Pair<T1>&);             
};

template<typename T>
template<typename T1>
Pair<T>& Pair<T>::operator=(Pair<T1>& temp)
{

    this->pair1 =temp.pair1*10;//At this point
    this->pair2=temp.pair2;
    return *this;
}

int main()
{

    Pair<int>P1(10,20);
    Pair<int>P2(1,2);
    P2=P1;
    cout<<P2.pair1<<' '<<P2.pair2<<endl;
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

我得到了答案100 20.

它没有给出默认的分配答案.

这是C++模板完整指南中的输入错误吗?

C++模板:完整指南作者:David Vandevoorde,Nicolai M. Josuttis

出版商:Addison Wesley

发布日期:2002年11月12日ISBN:0-201-73484-2页数:552

Col*_*mbo 14

复制赋值运算符确实是通过重载解析隐式声明和考虑的.

用户声明的复制赋值运算符X::operator=是类[..] 的非静态非模板成员函数X.

如果类定义未显式声明复制赋值运算符,则会式声明一个.[..]类的隐式声明的复制赋值运算符X将具有该表单

X& X::operator=(const X&)
Run Code Online (Sandbox Code Playgroud)

如果

  • 每个直接基类BX具有复制赋值运算符,其参数的类型的const B&,const volatile B&或者B,与
  • 对于X属于类类型M(或其数组)的所有非静态数据成员,每个这样的类类型都有一个复制赋值运算符,其参数类型为const M&,const volatile M&M.

除此以外, [..]

正如您所看到的,隐式声明的复制赋值运算符Pair<int>有一个类型的参数Pair<int> const&- const特别注意!如果两者都可以绑定到参数,则重载决策有利于非const引用const,[over.ics.rank]/3:

除非满足以下规则之一,否则相同形式的两个隐式转换序列是无法区分的转换序列:

-标准转换序列S1比标准转换序列更好的转换序列 S2,如果

  • [..]
  • S1并且S2是引用绑定(8.5.3),引用引用的类型是除了顶级cv限定符之外的相同类型, 并且引用初始化S2引用的类型比类型更符合cv引用初始化的S1 引用.

模板的特化缺少const参考参数中的a,因此它是更好的匹配并被选中.


Bar*_*zKP 6

默认赋值运算符接受该参数作为const引用:http://en.cppreference.com/w/cpp/language/as_operator.

您已经定义了一个版本const,并且在重载解析的情况下您的版本更好(不需要转换).

尝试以下更改:

int main()
{
    Pair<int>P1(10,20);
    Pair<int>P2(1,2);
    const Pair<int>& x = P1;
    P2=x;
    cout<<P2.pair1<<' '<<P2.pair2<<endl;
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

看到预期的结果.