[英]Implicit conversion to a C++ template object
I have a class A: 我有一个A类:
template <typename T, int I> struct A {};
and a class B. I would like object's of type B to implicitly convert to A when given as function arguments. 和B类。我希望类型B的对象在作为函数参数给出时隐式转换为A. B looks like this:
B看起来像这样:
template <typename T>
struct B {
operator A<T,0> &() const { return *new A<T,0>(); }
};
However, my test (below) fails with GCC 4.5, giving the error: no matching function for call to 'test(B&)' Where am I going wrong here? 但是,我的测试(下面)失败了GCC 4.5,给出错误: 没有匹配函数来调用'test(B&)'我在哪里错了? Do other compilers also reject this?
其他编译器也拒绝这个吗?
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;
}
ps I've now put my own solution in an answer below. ps我现在把自己的解决方案放在下面的答案中。
Unrelated to your problem but return *new A<T,0>();
与您的问题无关但
return *new A<T,0>();
is wrong since it 这是错的
leaks memory invites a memory leak. 泄漏记忆
引发内存泄漏。 You should not use
new
here. 你不应该使用
new
位置。 return A<T, 0>();
and removing the reference from the return type works just fine and does not leak memory. 并从返回类型中删除引用工作正常,并不会泄漏内存。
If you want an implicit conversion from B to A you would need either: 如果您想要从B到A的隐式转换,您需要:
A cast operator on B: B上的演员:
operator A<T,0>();
or an A constructor which takes a B reference: 或者是一个采用B引用的构造函数:
A( const B& other );
or for B to derive from A. What you have declared: 或者B来自A.你宣称:
operator A<T,0> &() const;
looks a bit like an ill-declared address-of overload. 看起来有点像一个错误声明的重载地址。
However, since test() takes a reference (and non-const at that), the casting operator option won't work. 但是,由于test()接受引用(并且非const),因此转换操作符选项将不起作用。
This is what I've tested: 这是我测试过的:
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;
}
Conversion to A by initialising a local variable works fine. 通过初始化局部变量转换为A工作正常。
Are you sure you actually want such an implicit conversion here? 你确定你真的想要这样的隐式转换吗? It sounds like a perfect way to confuse yourself or another maintainer, or worse, call a function using the wrong argument because the implicit conversion allows it.
这听起来像是混淆自己或其他维护者的完美方式,或者更糟糕的是,使用错误的参数调用函数,因为隐式转换允许它。 Instead, consider a
make_A
template like std::make_pair
to explicitly show your intention at the call site. 相反,请考虑像
std::make_pair
这样的make_A
模板,以明确显示您在呼叫站点的意图。
Providing an overload of test
like the following will enable to write test(b)
as in the question. 提供如下所述的
test
过载将使得能够在问题中编写test(b)
。
For example: 例如:
template <typename T>
void test(B<T> const &b) {
test( static_cast< A<T,0>& >( b ) );
}
test(b); // caller
If such overload isn't allowed but you are allowed to modify B
's definition, how about providing member function which returns A
like the following, instead of conversion function? 如果不允许这样的重载但你可以修改
B
的定义,那么如何提供返回A
成员函数,而不是转换函数?
template <typename T>
struct B {
A<T,0> &to_A() const { return *new A<T,0>(); }
};
test( b.to_A() );
If you aren't allowed to modify B
's definition, the above to_A
will be a free function like the following instead of member function: 如果不允许修改
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 ) );
Hope this helps 希望这可以帮助
This fails in VC++ too. 这在VC ++中也失败了。 To make it work, add this method:
要使其工作,请添加以下方法:
template <typename T>
void test(B<T> &b)
{
test( static_cast< A<T,0>& > (b) );
}
This will take an actual B
, explicitly do the conversion (via static_cast
), and then call test
using the A
we just made. 这将采用实际的
B
,明确地进行转换(通过static_cast
),然后使用我们刚刚创建的A
调用test
。
I get errors when I run it though. 我运行时遇到错误。 I hope this is just example code, and you're not doing
delete &a
in your actual code. 我希望这只是示例代码,而您在实际代码中没有
delete &a
。 RobH gave a better conversion operator for you, and avoids the pointer messiness. RobH为您提供了更好的转换运算符,并避免指针混乱。
I've settled on using the pass by value conversion operator suggested by Konrad; 我已经决定使用Konrad建议的pass by value转换运算符; the explicit template function call of Let_Me_Be;
Let_Me_Be的显式模板函数调用; and I sprinkled a little bit of C++0x magic on top: an rvalue reference on the parameter to test.
我在顶部撒了一点C ++ 0x魔法:一个关于要测试的参数的右值参考。 (Or, should that be C++ 2011 now?)
(或者,现在应该是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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.