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)
}
Foo::operator=
的两个重载对于重载解析来说都是同样好的匹配,因此具有歧义性。对于Bar::operator=
,情况并非如此——在其他条件相同的情况下,重载解析更喜欢非模板而不是模板。因此,private操作符=
是一个更好的匹配项,但它当然会导致访问检查失败Foo(f2)
是临时的,不能绑定到非常量引用。按值获取其参数的重载是唯一可行的候选者Foo::operator=
的两个重载对于重载解析来说都是同样好的匹配,因此具有歧义性。对于Bar::operator=
,情况并非如此——在其他条件相同的情况下,重载解析更喜欢非模板而不是模板。因此,private操作符=
是一个更好的匹配项,但它当然会导致访问检查失败Foo(f2)
是临时的,不能绑定到非常量引用。按值获取其参数的重载是唯一可行的候选者啊哈。。我理解你的第二点,我的错,我完全忽略了。但是我仍然想知道为什么使用显式模板参数会改变行为。另外,您能提供一个参考来支持您的第三点吗?我不确定您所说的使用显式模板参数的
是什么意思。你比较哪两条线的行为?红鲱鱼。第3行和第4行是强制转换,强制转换生成临时变量,临时变量不绑定到非常量引用。Foo&operator=(Foo-Foo){return Foo;}
vstemplate Bar&operator=(Bar){return Bar;}
。前一种状态表示,调用不明确,作为第二种状态,调用无法访问私有成员。13.3.3/1如果F1
是一个非模板函数,F2
是一个函数模板专用化…啊哈。。我理解你的第二点,我的错,我完全忽略了。但是我仍然想知道为什么使用显式模板参数会改变行为。另外,您能提供一个参考来支持您的第三点吗?我不确定您所说的使用显式模板参数的是什么意思。你比较哪两条线的行为?红鲱鱼。第3行和第4行是强制转换,强制转换生成临时变量,临时变量不绑定到非常量引用。Foo&operator=(Foo-Foo){return Foo;}
vstemplate 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 ='