2011-08-27 116 views
3

如何用另一個函數包裝一個通用的 C++ std :: tr1 :: function對象,使得該函數首先執行後面的包裝函數?我已經試過:C++用另一個函數包裝一個通用的std :: tr1 ::函數

#include <tr1/functional> 

template <typename T> 
int wrapped(const std::tr1::function<int(T)>& f, T t) 
{ 
    return f(t); 
} 

template <typename T> 
std::tr1::function<int(T)> wrap(const std::tr1::function<int(T)>& f) 
{ 
    return std::tr1::bind(&wrapped, f, std::tr1::placeholders::_1); 
} 

int foo(int i) { return i; } 

int main(int argc, char** argv) 
{ 
    std::tr1::function<int(int)> f = 
    wrap(std::tr1::bind(&foo, std::tr1::placeholders::_1)); 
    f(1); 
    return 0; 
} 

但這返回與編譯器錯誤(G ++):

wrap.cpp: In function ‘int main(int, char**)’: 
wrap.cpp:22: error: no matching function for call to ‘wrap(std::tr1::_Bind<int (*()(std::tr1::_Placeholder<1>))(int)>)’ 

回答

2

我看到你的代碼的兩個問題。首先,wrapped不是函數,它是一個函數模板,因此它在生成的程序中不存在。你不能取一個函數模板的地址。而應該指定此模板的實例化採取的地址:

template <typename T> 
std::tr1::function<int(T)> wrap(const std::tr1::function<int(T)>& f) 
{ 
    return std::tr1::bind(&wrapped<T>, f, std::tr1::placeholders::_1); 
} 

二(和多數民衆贊成你的編譯器是想告訴你)打電話wrap時,必須明確指定模板參數。編譯器無法從提供的參數中推導出參數。

std::tr1::function<int(int)> f = 
    wrap<int>(std::tr1::bind(&foo, std::tr1::placeholders::_1)); 

我真的不明白std::bindtr1::bind作品在裏面怎麼樣。但我明白返回的類型與簡單的函數指針有很大的不同,因此不允許編譯器清楚地讀取模板參數推導的類型。所以在這些情況下,您需要明確指定類型。

2

此代碼有兩個問題。一個很容易固定,另一個不太容易。

#include <tr1/functional> 

template <typename T> 
int wrapped(const std::tr1::function<int(T)>& f, T t) 
{ 
    return f(t); 
} 

template <typename T> 
std::tr1::function<int(T)> wrap(const std::tr1::function<int(T)>& f) 
{ 
    return std::tr1::bind(&wrapped<T>, f, std::tr1::placeholders::_1); // <- prob 1 
} 

int foo(int i) { return i; } 

int main(int argc, char** argv) 
{ 
    std::tr1::function<int(int)> f = 
    wrap(std::tr1::function<int(int)>(std::tr1::bind(&foo, // <- prob 2 
           std::tr1::placeholders::_1))); 
    f(1); 
    return 0; 
} 
  1. (一個小問題)wrapped是一個函數模板,因此不能被約束。你需要一個功能。幸運的是,您可以指定wrapped<T>
  2. (更大的問題)bind不返回std::tr1::function<>,它返回一些其他函數對象。您無法調用接受std::tr1::function<>的函數模板,因爲函數模板沒有用戶定義的參數轉換。您需要明確地自行完成轉換。我不確定你可以不用去C++ 11。在C++ 11中,您可以使用auto和後綴結果類型符號來重寫wrap,因此它可以接受任何內容,而不僅僅是function<int(T)>

編輯 Fiktik是正確的,因爲它足以說wrap<int>。隱式參數轉換的確適用於它。

相關問題