请考虑以下代码:
template<typename T>
bool function1(T some_var) { return true; }
template <typename T>
bool (*function2())(T) {
return function1<T>;
}
void function3( bool(*input_function)(char) ) {}
Run Code Online (Sandbox Code Playgroud)
如果我打电话
function3(function2<char>());
Run Code Online (Sandbox Code Playgroud)
没关系.但是,如果我打电话
function3(function2());
Run Code Online (Sandbox Code Playgroud)
编译器给出的错误是它无法推导出模板的参数.
请问,你可以建议(提出一个想法)如何重写function1和/或function2(可能,基本上是用类重写)来使它好吗?
*添加*
我正在尝试做一些简单的事情,比如Boost.LambdaLib中的lambda表达式(可能是,我的方法不对):
sort(some_vector.begin(), some_vector.end(), _1 < _2)
Run Code Online (Sandbox Code Playgroud)
我这样做了:
template<typename T>
bool my_func_greater (const T& a, const T& b) {
return a > b;
}
template<typename T>
bool my_func_lesser (const T& a, const T& b) {
return b > a;
}
class my_comparing {
public:
int value;
my_comparing(int value) : value(value) {}
template <typename T>
bool (*operator<(const my_comparing& another) const)(const T&, const T&) {
if (this->value == 1 && another.value == 2) {
return my_func_greater<T>;
} else {
return my_func_greater<T>;
}
}
};
const my_comparing& m_1 = my_comparing(1);
const my_comparing& m_2 = my_comparing(2);
Run Code Online (Sandbox Code Playgroud)
有用:
sort(a, a + 5, m_1.operator< <int>(m_2));
Run Code Online (Sandbox Code Playgroud)
但我希望它不需要像LambdaLib中那样的模板参数.
编译器不使用表达式上下文来推导其模板参数.对于编译器,function3(function2());看起来像
auto tmp = function2();
function3(tmp);
Run Code Online (Sandbox Code Playgroud)
它不知道什么function2模板参数.
从返回类型扣除是不可能的.因此function2无法从您期望的返回类型中推断出来.
然而,可以推导出演员.所以你可以不幸的是没有标准的语法来声明强制转换操作符没有typedef而且类型推导不能通过typedef工作.以下定义适用于某些编译器(适用于G ++ 4.5,在VC++ 9中不起作用):function2用一个辅助结构代替:
struct function2 {
template <typename T>
(*operator bool())(T) {
return function1<T>;
}
};
Run Code Online (Sandbox Code Playgroud)
(另请参阅用于转换为函数指针的C++转换运算符).
呼叫应该看起来仍然相同.
注意:C++ 11引入了可以模板化的替代typedef语法.这将是:
struct function2 {
template <typename T>
using ftype = bool(*)(T);
template <typename T>
operator ftype<T>() {
return function1<T>;
}
};
Run Code Online (Sandbox Code Playgroud)
但我手边没有G ++ 4.7和VC++ 10,所以我无法测试它是否真的有用.
广告新增:
Boost.Lambda中的技巧是它不返回函数,而是函数.而仿函数可以是类模板.所以你有:
template<typename T>
bool function1(T some_var) { return true; }
class function2 {
template <typename T>
bool operator()(T t) {
function1<T>;
}
};
template <typename F>
void function3( F input_function ) { ... input_function(something) ... }
Run Code Online (Sandbox Code Playgroud)
现在你可以写:
function3(function2);
Run Code Online (Sandbox Code Playgroud)
它将解决内部模板function3.所有STL都将仿函数作为模板,因此可以与所有STL一起使用.
但是如果不想function3作为模板,还有一种方法.与函数指针不同,std::function(仅限C++ 11,boost::function用于较旧的编译器)模板可以从任何仿函数(包括普通函数指针)构造.所以鉴于上述情况,你可以写:
void function3(std::function<bool ()(char)> input_function) { ... input_function(something) ... }
Run Code Online (Sandbox Code Playgroud)
现在你仍然可以打电话:
function3(function2());
Run Code Online (Sandbox Code Playgroud)
关键是std::function有一个模板构造函数,它在内部生成一个模板包装器并存储一个指向它的方法的指针,该方法可以在没有其他模板的情况下调用.
| 归档时间: |
|
| 查看次数: |
405 次 |
| 最近记录: |