模板函数的隐式转换
Implicit conversion of template function
我有一个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;
}
您发布的代码中有两个主要问题。
-
编译器不会将
B<int>
转换为A<int>
以推导出要int
foo
的模板参数。你必须帮助编译器。用: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&) {}
此外,A
friend
声明是不正确的。它声明了一个非模板函数foo
是A<T>
的friend
。如果你想foo<T>
成为A<T>
的friend
,你必须稍微改变你的代码。
// Declare the class template A first.
template <typename T> class A;
// Declare the funtion template foo next.
template <typename T> void foo(A<T>);
// Declare foo<T> to be friend of A<T> in the definition of A.
template <typename T>
struct A {
...
friend void foo<>(A);
};
这是一个为我成功构建的完整程序。
template <typename T> struct B;
template <typename T> struct A;
template <typename T> void foo(A<T> a);
template <typename T>
struct A {
A(const B<T>& b) : x{b.a.x} {} // Conversion from B to A, way 1
A(T x) : x{x} {}
T x;
friend void foo<>(A);
};
template <typename T>
void foo(A<T> a) {}
template <typename T>
struct B {
B() : a{0} {}
A<T> a;
// This is not necessary for conversion of B<T> to A<T>
// operator A<T>() { return a; } // Conversion from B to A, way 2
};
int main()
{
foo<int>(B<int>());
foo(static_cast<A<int>>(B<int>()));
}
foo()
将非常量引用作为输入。B
的转换运算符返回一个临时A
对象,并且 temp 不能绑定到非常量引用参数。这就是您对foo()
调用无法编译的原因。
如果要更改输入参数以改为采用 const 引用,它可以绑定到 temp 对象。但是,A
有一个复制构造函数,该构造函数将对B
对象的 const 引用作为输入,因此对foo()
的调用可能仍然不明确。 构造临时B
对象后,编译器应该调用A
复制构造函数,B
作为输入,还是应该调用返回A
的B
转换运算符? 我不确定标准对此有何规定,或者编译器如何实现这一点。
相关文章:
- 转换函数,将 std::数组的双精度作为参数或双精度作为参数单独转换
- C++:用户定义的显式类型转换函数错误
- 为什么下面带有非常量转换函数的代码没有歧义?
- 为什么转换函数声明不需要至少一个定义类型说明符
- PCL:当我在setConditionFunction中使用std::bind 时,没有合适的转换函数
- C++ 通过自定义赋值运算符隐式转换函数参数
- 当我使用 void 函数的返回值(通过强制转换函数指针)时,究竟会发生什么?
- 在C++中自动向下转换函数参数
- static_cast:转换函数模板——它们真的有效吗
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类
- 隐式转换函数的返回对象时是否会影响性能?
- C++不存在合适的转换函数
- 为什么允许 int 和 const int 使用不同的转换函数?
- 使用转换函数直接初始化
- 为什么用户定义的转换函数模板不能有推导的返回类型?
- 为什么我会收到转换函数错误
- 选择用于赋值初始化的转换函数的优先级
- 我收到错误:没有合适的转换函数从 std::basic_istream<char、std::char_traits<char>> 到 char 存在
- 具有转换函数的 lambda,指向具有 C++ 链接的函数的指针
- 使用模板和部分专用化生成类型转换函数