我有一个A类,其中实施了大多数操作。另外,我有另一个B类只包含A的成员。我希望A中的操作可以直接应用于B.所以我定义了一个转换操作。但是编译器抱怨"错误:没有匹配函数来调用' foo'"。隐式转换有什么问题?如何实现?感谢。
编辑:如果我将操作符重载添加到A并希望B直接使用它会怎么样?
template <typename T> struct B;
template <typename T>
struct A {
A(const B<T>& b) {} // Conversion from B to A, way 1
friend void foo(const A&);
// Addition
friend A operator+(const A&, const A&);
};
template <typename T>
void foo(A<T>& a) {}
// Addition
template <typename T>
A<T> operator+(const A<T>& a1, const A<T>& a2) { return A<T>(); }
template <typename T>
struct B {
B() {}
A<T> a;
operator A<T>() { return a; } // Conversion from B to A, way 2
// Addition
B(const A<T>& a) : a(a) {}
};
int main()
{
B<int> b;
foo(b);
auto bb = b+b;
}
答案 0 :(得分:4)
您发布的代码存在两个主要问题。
编译器不会将B<int>
转换为A<int>
,以便将foo
的模板参数推断为int
。您必须帮助编译器。使用:
foo<int>(B<int>());
或
foo(static_cast<A<int>>(B<int>()));
这只能解决问题的一半。
转换函数,无论编译器使用哪一个,都会产生临时对象。临时对象无法绑定到A<int>&
。你必须使用
template <typename T> void foo(A<T>) {}
或
template <typename T> void foo(A<T> const&) {}
此外,friend
中的A
声明不正确。它声明非模板函数foo
为friend
的{{1}}。如果您希望A<T>
成为foo<T>
的{{1}},则必须稍微更改一下代码。
friend
这是一个为我成功构建的完整程序。
A<T>
答案 1 :(得分:0)
foo()
将非const引用作为输入。 B
的转换运算符返回临时A
对象,并且temp不能绑定到非const引用参数。这就是你对foo()
的调用无法编译的原因。
如果您要更改输入参数以取代const引用,它可以绑定到临时对象。但是,A
有一个复制构造函数,它将B
对象的const引用作为输入,因此您对foo()
的调用可能仍然不明确。在构造临时B
对象之后,编译器是应该使用A
作为输入调用B
复制构造函数,还是应该调用返回{B
转换运算符的A
转换运算符1}?我不确定标准是关于什么的,或者编译器如何实现它。