2014-03-01 107 views
0

我很新的C++而不是太知道我需要提供至少提供可重复的例子,但这里是我的问题呢:C++查找函数返回类型

在C++中,我想创建一个函数(f1)能够具有另一个函数(f2)作为输入,它将在循环中进行评估并记录/输出。

但是,根据函数的输出类型(f2),f1的输出必须改变。即如果f2输出一个double,那么我需要一个数组/向量作为f1的输出类型,但是如果f2输出一个数组/向量,那么我需要一个二维数组/矩阵作为f1的输出类型。有什么能够帮助我在执行循环之前找出f1的返回类型吗?

任何帮助或例子,我可以遵循将不胜感激。

+2

一个简单的模板应该能够做到这一点。 – chris

+0

函数模板就是答案。如果你想能够从f2 tho返回一个数组,你需要专门化。 –

回答

3

这听起来像你正在寻找模板。这里http://en.wikipedia.org/wiki/Template_%28C%2B%2B%29:你可以从这里开始http://msdn.microsoft.com/en-us/library/y097fkab.aspx或在这里:http://www.codeproject.com/Articles/257589/An-Idiots-Guide-to-Cplusplus-Templates-Part-1

模板允许你写一个函数或类一次,有它不同的数据类型的工作。请记住,如果代码必须在数据类型之间切换,则需要更复杂的模板 - 专业化 - 或者可能不是您需要的模板。

0

模板是正确的选择。如下是任何可调用对象,f功能,并从调用函数(live example)返回填充返回的值返回类型的std::array(5元随意选择):

template<typename F> 
auto foo(F f) -> std::array<decltype(f()), 5> { //decltype(f()) is return type 
    std::array<decltype(f()), 5> ret; 
    std::fill(std::begin(ret), std::end(ret), f()); //fill ret with values 
    return ret; 
} 

注意的唯一的事情如果传入的函数具有任何参数,则该变化是f(),在所有情况下,都需要变为f(arg1, arg2, ...)。另外请注意,这将填充一次调用f的结果副本。如果您想每个元素拨打f一次,请使用std::generate并用f替换f()。但是,如果您确实使用std::generate,并且该函数具有参数,那么您必须使用类似std::bind之类的内容,而这真的是越来越少的话题。

0

查找普通函数结果类型的最简单方法是使用std::function

#include <functional> 
#include <iostream> 
#include <typeinfo> 
#include <type_traits> 
#include <vector> 
using namespace std; 

template< class Function > 
using Pure_function_ = typename remove_pointer<Function>::type; 

template< class Function > 
using Result_type_ = typename function<Pure_function_<Function>>::result_type; 

template< class Function > 
auto three_times(Function f) 
    -> vector< Result_type_<Function> > 
{ 
     vector< Result_type_<Function> > result; 
     for(int x : {1, 2, 3}) 
     { 
      result.push_back(f(x)); 
     } 
     return result; 
} 

auto double_foo(int x) -> double { return 2*x; } 
auto vector_foo(int x) -> vector<int> { return vector<int>(5, 3*x); } 

auto main() 
    -> int 
{ 
    auto const a = three_times(double_foo); 
    cout << typeid(function<decltype(double_foo)>::result_type).name() << endl; 

    auto const b = three_times(vector_foo); 
    cout << typeid(b).name() << endl; 

    auto const c = three_times(&vector_foo); 
    cout << typeid(c).name() << endl; // Same as above. 
}