Deduce返回类型的函数指针或函子

时间:2014-12-07 21:33:07

标签: c++ templates c++03 type-deduction

我试图推断出可调用类型的返回类型,即函数指针或函子。

我之前曾问过并得到一个答案,显示如何为函数指针执行此操作,并提供有关如何为仿函数执行此操作的提示。

Function return type deduction in C++03

基于此,我有这个辅助结构,它现在适用于仿函数但不再适用于函数指针。

// functors
template<class T>
struct Return;
{
    typedef typename T::result_type type;
};

// function pointers
template<class R>
struct Return<R (*)()>
{
        typedef R type;
};

这适用于提供result_type typedef但不提供函数指针的协作仿函数。 clang给出了以下内容:

  

错误:输入&#39; int(*)(int)&#39;不能在&#39; ::&#39;之前使用因为它没有成员

typedef typename T::result_type type;

我很困惑为什么这不是SFINAE错误会继续发生并抓住Return的专业化。

你可以自己尝试一下,也可以看一些我正在做的事情。

http://coliru.stacked-crooked.com/a/53f4c8c90787e329

上下文

这是建立在这个问题上的。

“Overload” function template based on function object operator() signature in C++98

在那个问题中,我试图创建一个函数模板,通过使用传递的映射函数将std :: vector映射到新的std :: vector。现在我尝试从容器中映射,该容器提供迭代其内容的方法。在该问题的答案中,函数模板具有以下形式:

template<typename F, typename T>
typename expr_check<sizeof(declval<F>()(declval<T>())), std::vector<T> >::type
map_vec(F fnc, const std::vector<T>& source)

其中F是可调用类型,T既是类型F采用的参数类型,也是返回类型std::vector<T>的参数化。请参阅问题以获取declval的解释。

现在我希望函数模板采用容器类型,称之为C。我的想法是T应该在这里被推断为类型F的返回类型,因此不再是参数本身。现在我正试图让模板使用这个签名:

template<typename F, typename C>
typename expr_check<sizeof(declval<F>()(declval<int>())),
        std::vector<typename Return<F>::type> >::type
map_vec(F fnc, const C& source);

2 个答案:

答案 0 :(得分:3)

您的错误仅适用于零参数。

由于pre-C ++ 11没有可变参数模板,因此您必须为每个计数添加一个专门化,直至达到限制。

如果您可以使用C ++ 11功能,只需使用std::result_of

答案 1 :(得分:2)

这是Deduplicator捕获的一个愚蠢的错误。

工作示例:

http://coliru.stacked-crooked.com/a/cdb79bbdeedfaa65

问题很简单,需要Return的专门化适合将要使用的功能签名。

// functors
template<class T>
struct Return
{
    typedef typename T::result_type type;
};

// function pointers
template<class R, class T>
struct Return<R (*)(T)>
{
        typedef R type;
};

// function pointers
template<class R, class T, class U>
struct Return<R (*)(T, U)>
{
        typedef R type;
};