【问题标题】:Template assignment operator doesn't replace the default assignment operator模板赋值运算符不会替换默认的赋值运算符
【发布时间】:2015-02-25 01:21:58
【问题描述】:

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. 约苏蒂斯

出版商:艾迪生韦斯利

发布日期:2002 年 11 月 12 日 页数:552

【问题讨论】:

  • 我认为Pair&lt;T1&gt;&amp; temp在传入非const左值时不涉及const限定,所以这是一个更好的转换序列
  • 两个赋值运算符都存在于Pair 中,并参与重载决议。因为模板化的引用采用非 const 引用,而隐式声明的引用采用 const 引用,在这种情况下前者是更好的匹配。一旦您更改模板化的引用以获取 const 引用,隐式定义的引用就会按您的预期调用。 Live example

标签: c++ templates


【解决方案1】:

复制赋值运算符确实是隐式声明的,并由重载决议考虑。

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

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

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

如果

  • X 的每个直接基类 B 都有一个复制赋值运算符,其参数类型为 const B&amp;const volatile B&amp;B,并且
  • 对于X 的类类型M(或其数组)的所有非静态数据成员,每个此类类型都有一个复制分配 参数类型为 const M&amp;const volatile M&amp;M

否则,[..]

正如您所见,Pair&lt;int&gt; 的隐式声明的复制赋值运算符有一个 Pair&lt;int&gt; const&amp; 类型的参数 - 请特别注意 const!如果两者都可以绑定到参数 [over.ics.rank]/3:

两个相同形式的隐式转换序列是 不可区分的转换序列,除非以下之一 规则适用:

—— 标准转换序列S1是比标准转换序列更好的转换序列 S2如果

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

模板的特化在引用参数中缺少const,因此匹配更好,被选中。

【讨论】:

    【解决方案2】:

    默认赋值运算符接受参数作为 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;
    }
    

    查看预期结果。

    【讨论】:

      猜你喜欢
      • 2013-08-09
      • 1970-01-01
      • 2012-11-26
      • 2019-06-30
      • 2015-01-27
      • 1970-01-01
      • 2011-11-14
      • 2020-02-28
      相关资源
      最近更新 更多