2011-08-27 85 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>。隐式参数转换的确适用于它。

相关问题