2

由于某些复杂的原因,我想将任何支持的类型 T(来自模板)转换为我选择的类型列表。为此,我尝试使用名为“Convert”的模板结构。例如:

Convert<short>::type should be int
Convert<int>::type should be int
Convert<char>::type should be int
Convert<float>::type should be double
Convert<double>::type should be double
Convert<const char*>::type should be std::string
Convert<std::string>::type should be std::string
etc.

以上这些很容易使用模板专业化来实现。但是有一种情况会导致问题:

Convert<T>::type where T is a functor should be T

为了处理这个问题,我想我必须使用SFINAE但我无法让它编译。

下面的代码给了我“部分专业化不能匹配主模板的参数列表”(即禁止写“转换”):

template<typename T, typename = decltype(&T::operator())>
struct Convert<T>       { typedef T type; };

这给了我“模板参数在部分专业化中未使用或可推导”(即它认为未使用 T):

template<typename T>
struct Convert<typename std::enable_if<std::is_function<typename T::operator()>::value,T>::type>
 { typedef T type; };

我不知道该怎么做,我所有的尝试都导致了上述两个错误之一。

编辑:我想用相同的模型捕捉其他通用的东西,所以我不能只在非专业结构中写“typedef T type”。

谢谢

4

1 回答 1

2

我建议您使用第一种方法,但要使其正常工作,您必须

使用一个未使用的模板参数声明主模板:

template <class T, class = void> Convert;

void为您现在使用的模板的所有特化添加一个参数。

像这样定义您的“函子专业化”:

template<typename T, typename std::enable_if<std::is_function<typename T::operator()>::value,void>::type>

这意味着void如果第二个参数是仿函数(因此它与默认模板参数匹配),则您制作第二个参数,如果不是,则不存在。

顺便说一句,你为什么使用typenamein typename T::operator()?AFAIK,operator()不是一种类型。

于 2010-07-24T10:37:40.683 回答