C++ 关于函数/运算符重载的混淆

C++ 关于函数/运算符重载的混淆,c++,C++,考虑以下自包含程序 #include <iostream> template<typename Ty> struct Foo { Foo& operator=(Foo foo){ return foo; } private: Foo& operator=(Foo& foo){ return foo; } }; template<typename Ty> struct Bar { template<t

考虑以下自包含程序

#include <iostream>
template<typename Ty>
struct Foo
{
    Foo& operator=(Foo foo){ return foo; }    
private:
    Foo& operator=(Foo& foo){ return foo; }
};
template<typename Ty>
struct Bar
{
    template<typename U>
    Bar& operator=(Bar<U> bar){ return bar; }
private:
    Bar& operator=(Bar& bar){ return bar; }
};

int main()
{
    Foo<int> f1, f2;
    f1 = f2;            // (1)
    Bar<int> b1, b2;
    b1 = b2;            // (2)
    f1 = Foo<int>(f2);  // (3)
    b1 = Bar<int>(b2);  // (4)
}
  • 为什么我执行显式强制转换的(3)和(4)都没有失败。为什么它不含糊,也不试图访问私有的引用重载

  • 为什么在案例(2)中,它优先考虑引用重载,而不是值重载函数/运算符
  • 注意一个版本,以防您想使用代码。 注意请提供适当的参考资料

  • Foo::operator=
    的两个重载对于重载解析来说都是同样好的匹配,因此具有歧义性。对于
    Bar::operator=
    ,情况并非如此——在其他条件相同的情况下,重载解析更喜欢非模板而不是模板。因此,private
    操作符=
    是一个更好的匹配项,但它当然会导致访问检查失败

  • Foo(f2)
    是临时的,不能绑定到非常量引用。按值获取其参数的重载是唯一可行的候选者

  • 它不优先考虑引用重载,而是优先考虑非模板重载。您可以通过切换它们来确认这一点

  • Foo::operator=
    的两个重载对于重载解析来说都是同样好的匹配,因此具有歧义性。对于
    Bar::operator=
    ,情况并非如此——在其他条件相同的情况下,重载解析更喜欢非模板而不是模板。因此,private
    操作符=
    是一个更好的匹配项,但它当然会导致访问检查失败

  • Foo(f2)
    是临时的,不能绑定到非常量引用。按值获取其参数的重载是唯一可行的候选者

  • 它不优先考虑引用重载,而是优先考虑非模板重载。您可以通过切换它们来确认这一点


  • 啊哈。。我理解你的第二点,我的错,我完全忽略了。但是我仍然想知道为什么使用显式模板参数会改变行为。另外,您能提供一个参考来支持您的第三点吗?我不确定您所说的使用显式模板参数的
    是什么意思。你比较哪两条线的行为?红鲱鱼。第3行和第4行是强制转换,强制转换生成临时变量,临时变量不绑定到非常量引用。
    Foo&operator=(Foo-Foo){return Foo;}
    vs
    template Bar&operator=(Bar){return Bar;}
    。前一种状态表示,调用不明确,作为第二种状态,调用无法访问私有成员。13.3.3/1如果
    F1
    是一个非模板函数,
    F2
    是一个函数模板专用化…啊哈。。我理解你的第二点,我的错,我完全忽略了。但是我仍然想知道为什么使用显式模板参数会改变行为。另外,您能提供一个参考来支持您的第三点吗?我不确定您所说的使用显式模板参数的
    是什么意思。你比较哪两条线的行为?红鲱鱼。第3行和第4行是强制转换,强制转换生成临时变量,临时变量不绑定到非常量引用。
    Foo&operator=(Foo-Foo){return Foo;}
    vs
    template Bar&operator=(Bar){return Bar;}
    。前一种状态表示,调用不明确,作为第二种状态,调用无法访问私有成员。13.3.3/1如果
    F1
    是一个非模板函数,
    F2
    是一个函数模板专用化。。。
    1>Source.cpp(8): warning C4522: 'Foo<int>' : multiple assignment operators specified
    1>          Source.cpp(20) : see reference to class template instantiation 'Foo<int>' being compiled
    1>Source.cpp(21): error C2593: 'operator =' is ambiguous
    1>          Source.cpp(7): could be 'Foo<int> &Foo<int>::operator =(Foo<int> &)'
    1>          Source.cpp(5): or       'Foo<int> &Foo<int>::operator =(Foo<int>)'
    1>          while trying to match the argument list '(Foo<int>, Foo<int>)'
    1>Source.cpp(23): error C2248: 'Bar<int>::operator =' : cannot access private member declared in class 'Bar<int>'
    1>          Source.cpp(15) : see declaration of 'Bar<int>::operator ='