2014-03-01 109 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. 
}