我有一个A类:
template <typename T, int I> struct A {};
和类B.我希望类型B的对象在作为函数参数给出时隐式转换为A. B看起来像这样:
template <typename T>
struct B {
operator A<T,0> &() const { return *new A<T,0>(); }
};
然而,我的测试(下面)因GCC 4.5而失败,给出错误:没有匹配函数来调用'test(B&amp;)'我在哪里错了?其他编译器也拒绝这个吗?
template <typename T, int I>
void test(A<T,I> &a) { delete &a; }
int main(int argc, char *argv[])
{
B<int> b;
test(b);
return 0;
}
P.S。我现在把自己的解决方案放在下面的答案中。
答案 0 :(得分:3)
与您的问题无关,但return *new A<T,0>();
错误,因为泄漏内存会导致内存泄漏。你应该不在这里使用new
。 return A<T, 0>();
并从返回类型中删除引用可以正常工作并且不会泄漏内存。
答案 1 :(得分:2)
如果您想要从B到A的隐式转换,您需要:
B上的演员:
operator A<T,0>();
或带有B引用的A构造函数:
A( const B& other );
或者B来自A.你声明的内容:
operator A<T,0> &() const;
看起来有点像一个错误声明的重载地址。
但是,由于test()接受引用(并且非const),因此转换操作符选项将不起作用。
这是我测试过的:
template <typename T, int I> struct A {};
template <typename T>
struct B {
//operator A<T,0> &() const { return *new A<T,0>(); }
template< int I >
operator A<T, I> () const { return A< T, 0 >(); }
};
template <typename T, int I>
void test(A<T,I> &) { }
int f()
{
B<int> b;
A<int, 0> a( b );
test(a); // <-- Success
test(b); // <-- Failure, "could not deduce template argument"
return 0;
}
通过初始化局部变量转换为A可以正常工作。
答案 2 :(得分:1)
你确定你真的想要这样的隐式转换吗?这听起来像是混淆自己或其他维护者的完美方式,或者更糟糕的是,使用错误的参数调用函数,因为隐式转换允许它。相反,请考虑make_A
std::make_pair
模板,以明确显示您在呼叫站点的意图。
答案 3 :(得分:1)
如下所示提供test
的重载将允许写入
问题test(b)
例如:
template <typename T>
void test(B<T> const &b) {
test( static_cast< A<T,0>& >( b ) );
}
test(b); // caller
如果不允许这样的重载但允许您修改B
定义,如何提供返回A
的成员函数
如下所示,而不是转换功能?
template <typename T>
struct B {
A<T,0> &to_A() const { return *new A<T,0>(); }
};
test( b.to_A() );
如果您不允许修改B
的定义,则上述to_A
将是。{
一个像下面这样的自由函数而不是成员函数:
template <typename T>
A<T,0> &to_A(B<T> const &b) {
return static_cast< A<T,0>& >( b );
}
test( to_A( b ) );
希望这有帮助
答案 4 :(得分:0)
这在VC ++中也失败了。要使其工作,请添加以下方法:
template <typename T>
void test(B<T> &b)
{
test( static_cast< A<T,0>& > (b) );
}
这将采用实际的B
,明确地进行转换(通过static_cast
),然后使用我们刚刚制作的test
来调用A
。
我运行时遇到错误。我希望这只是示例代码,而您在实际代码中没有delete &a
。 RobH为您提供了一个更好的转换运算符,并避免指针混乱。
答案 5 :(得分:0)
我已经决定使用Konrad建议的pass by value转换运算符; Let_Me_Be的显式模板函数调用;我在顶部撒了一点C ++ 0x魔法:一个关于要测试的参数的右值参考。 (或者,现在应该是C ++ 2011吗?)
template <typename T, int I> struct A { int x; };
template <typename T>
struct B {
operator A<T,0> () const { return A<T,0>(); }
};
template <typename T, int I>
void test(A<T,I> &&a) { a.x=7; printf("%d\n", x); }
int main(int argc, char *argv[])
{
B<int> b;
test<int,0>(b);
return 0;
}