0

假设我有一个这样的函数模板:

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

然后在另一个.h文件中,我有一个模板类Foo,它具有:

public: operator T*() const;

现在,我意识到这些是不同的 T。但是如果我Foo<Bar> f在堆栈上有一个变量,将它强制为任何类型的指针的唯一方法就是调用operator T*(). 然而,如果 call doStuff(f),GCC 会抱怨doStuff不能Foo<Bar>自动使用运算符T*()强制转换Bar*,然后使用Baras专门化函数模板T

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

4

5 回答 5

3

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

如果 Foo<T> 是您要运行的唯一其他模板,最好的解决方案是添加:

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));
}

虽然有点冗长;-)

于 2008-10-12T21:39:03.867 回答
2

这可能值得一试:

doStuff<Bar>(f);

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

于 2008-10-12T21:40:16.860 回答
0

Leon 的想法可能是最好的。但在紧要关头,您也可以显式调用强制转换运算符:

doStuff(static_cast<Bar*>(f));
于 2008-10-13T00:58:34.153 回答
-1

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


template 
inline
void 
doStuff(T& arrRef)
{
  doStuff(&arrRef);
}
于 2008-10-12T21:16:29.390 回答
-1

好吧,T* 并不是您认为的与 T 不同的类型。指针是一个类型限定符。我不确定标准对此有何评论,但我会说,由于变量已经是 T 类型,它不会尝试再次转换。如果你想做一些自定义的东西来获取指针,重载 & 运算符。

于 2008-10-12T21:24:34.880 回答