2014-12-07 82 views
4

我想推导出可调用类型的返回类型,即函数指针或仿函数。Deduce函数指针或函子的返回类型

我以前问过,并得到了一个答案,显示如何做到这一点与函数指针提示如何做到这一点的函子。

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类型定义而不是函数指针仿函数。铛给出了以下几点:

error: type 'int (*)(int)' cannot be used prior to '::' because it has no members

typedef typename T::result_type type; 

我明白为什么这是不是会继续前进,赶上的Return专业化一SFINAE错误困惑。

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

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

语境

这建立在这个问题上。

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

在这个问题,我试图用通过映射函数来创建一个函数模板,将映射一个std ::向量到一个新的std ::向量。现在我试图从一个容器中进行映射,该容器提供了对其内容进行迭代的方法。在回答这个问题的函数模板有以下形式:

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是一个可调用类型和TF类型所采取的论点的类型和还参数化的返回类型,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

你的错误只专注于零参数。你想专注于任意的参数。 – Deduplicator 2014-12-07 21:36:36

+0

我刚刚意识到这一点!那真是头脑凌乱,我放弃了也很容易。 – Praxeolitic 2014-12-07 21:37:18

回答

3

您的错误只针对精确为零的参数。因为pre-C++ 11没有可变参数模板,所以您将不得不为每个计数添加一个专门化以达到您的限制。

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

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