【问题标题】:Catching functors using SFINAE in structure partial specialisation在结构偏特化中使用 SFINAE 捕获函子
【发布时间】:2010-07-24 09:30:27
【问题描述】:

出于某种复杂的原因,我想将任何支持的类型 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,但我无法让它编译。

下面的代码给了我“partial specialization cannot match argument list for primary template”(即禁止写“Convert”):

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

而这个给了我“template parameter not used or deducible in partial specialization”(即它认为没有使用 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”。

谢谢

【问题讨论】:

  • 你是什么意思“抓住其他通用的东西”?
  • 您需要澄清“函子”的含义。功能也不错吗?或者它只是功能对象?如果是这样,那么operator() 是否过载?还是源自std::function_object?特定数量的参数?
  • 示例:"Convert::type is int if T is convertible to an int", or "Convert::type is ... if T has a begin and an end功能”等
  • @sbi:在上面的示例中,我尝试使用 operator()(任意数量的参数)来捕获函数对象;我可以处理其他专业的功能
  • @Tomaka17:你见过这个吗:stackoverflow.com/questions/257288/…? (链接已更改)

标签: c++ templates sfinae


【解决方案1】:

我建议您使用第一种方法,但要使其发挥作用,您必须这样做

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

template <class T, class = void> Convert;

void 参数添加到您现在使用的模板的所有特化中。

像这样定义你的“函子特化”:

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

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

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

【讨论】:

  • 好主意,谢谢。显然我什至不需要将void 添加到我的其他专业中。但是编译器暂时使用非专业结构,我会尝试让它工作。
  • 你可能是正确的类型名,无论如何我尝试了几个我认为是正确的 std::enable_if&lt;!std::is_void&lt;decltype(&amp;T::operator())&gt;::value&gt;::type 之类的东西
  • Convert&lt;T, typename std::enable_if&lt;true,void&gt;::type&gt; 工作正常,所以我的情况一定有问题
  • 我的第二条评论中的代码适用于 g++,但不适用于 MSVC++,但是我通过创建受stackoverflow.com/questions/257288/… 启发的“IsFunctor”类型使其在两个编译器上都适用,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多