作为函数模板的T *参数传递时,使用运算符T *强制模板类

时间:2008-10-12 21:07:01

标签: c++ templates coercion

假设我有一个这样的功能模板:

template<class T>
inline
void
doStuff(T* arr)
{
  // stuff that needs to use sizeof(T)
}

然后在另一个.h文件中,我有一个模板类Foo,其中包含:

public: operator T*() const;

现在,我意识到那些是不同的Ts。但是如果我在堆栈上有一个变量Foo<Bar> f,那么将它强制转换为任何类指针的唯一方法就是调用operator T*()。但是,如果致电doStuff(f),GCC会抱怨doStuff无法使用Foo<Bar>而不是自动使用运营商T*()来强制Bar*然后专门化该功能BarT的模板。

我有什么办法可以使用两个模板来完成这项工作吗?或者,模板函数的参数必须是真实的指针类型,还是将强制运算符的模板类传递给非模板函数?

5 个答案:

答案 0 :(得分:3)

海湾合作委员会是正确的。在模板参数中,只考虑完全匹配,类型转换不是。这是因为否则可能需要考虑无限(或至少指数)的转换量。

如果Foo&lt; T&gt;是你要运行的唯一其他模板,最好的解决方案是添加:

template<typename T> inline void doStuff(const Foo<T>& arr) {
    doStuff(static_cast<T*>(arr));
}

如果您遇到许多模板的问题,那么应该修复它:

#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
template<template <typename> class T, typename U> inline typename boost::enable_if<typename boost::is_convertible<T<U>, U*>::type>::type doStuff(const T<U>& arr) {
    doStuff(static_cast<U*>(arr));
}

虽然有点冗长; - )

答案 1 :(得分:2)

这可能值得一试:

doStuff<Bar>(f);

我认为这会导致编译器期望T *为Bar *然后使用Foo的运算符T *()来执行转换,但我不能说我已经尝试过了。

答案 2 :(得分:0)

莱昂的想法可能是最好的。但是在紧要关头,你也可以明确地调用强制转换操作符:

doStuff(static_cast<Bar*>(f));

答案 3 :(得分:-1)

我不确定为什么转换不起作用但您可以使用重载来解决问题


template 
inline
void 
doStuff(T& arrRef)
{
  doStuff(&arrRef);
}

答案 4 :(得分:-1)

嗯,就你认为的而言,T *并不是与T分开的类型。指针是类型限定符。我不确定标准是怎么说的,但我会说因为变量已经是T型,所以它不会再尝试转换。如果你想做一些自定义的东西来获得一个指针,重载&amp;操作