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

时间:2014-12-28 17:48:48

标签: 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;
}

我得到了答案100 20。

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

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

  

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

     

出版商:Addison Wesley

     

Pub Date:2002年11月12日ISBN:0-201-73484-2页数:552

2 个答案:

答案 0 :(得分:14)

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

  

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

如果类定义没有明确说明   声明一个复制赋值运算符,一个声明为隐式 。 [..]   类X的隐式声明的复制赋值运算符将会   有表格

X& X::operator=(const X&)
     

如果

     
      
  • B的每个直接基类X都有一个复制赋值运算符,其参数类型为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如果

     
      
  • [..]
  •   
  • S1S2是引用绑定(8.5.3),以及   引用引用是相同的类型,除了顶级cv限定符,   S2引用的引用引用的类型更多   cv-qualified,而不是S1初始化引用的类型   指
  •   

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

答案 1 :(得分:6)

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

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

尝试the following change

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;
}

查看预期结果。