正在学习C++11的新特性,用非类型模板写了一个函数包装器,我是这样写的:
#include <iostream>
#include <cstdlib>
#include <string>
#include <functional>
void hello() {
std::cout << "Hello, world!\n";
return;
}
template< std::function<void()> i>
void wrapper() {
i();
}
int main() {
std::function<void()> f = hello;
wrapper<f>();
return 0;
}
在VS2013上编译错误,提示是
“std::function”: 非类型模板参数“i”的类型非法
但是当我将wrapper的定义改成
template<void i()>
void wrapper() {
i();
}
将调用改成wrapper<hello>();
之后编译运行就一切正常了。请问这是什么原因?
另外请问std::function除了能包装匿名函数外,还有什么情况下与函数对象或者普通函数指针表现不同呢?谢谢。
Because non-type template arguments must be constant expressions. Because everything in the template must be determined at compile time.
http://en.cppreference.com/w/...
wrapper<f>()
where f is a variable, its value can only be determined during runtime. So the template cannot be compiled and passed. You can't wait until runtime and then Instantiate awrapper<f>
function and let i point to f, right?For pointers to functions, the valid arguments are pointers to functions with linkage (or constant expressions that evaluate to null pointer values)., so
<void i()>
can compile and pass:The way you write it,
template < std::function<void()> i >
, herei
is obviously a variable, not a type. If you want to declare a type, you should write it astemplate <typename Func>
. However, if it is declared as a type,wrapper
will of course not work, becausei()
is equivalent to instantiating an emptystd::function
object and does nothing. In the end, of course, you will not get the effect you want.Generally speaking, you should implement
The biggest function ofwrapper
like this to be normal.std::function
is to express anonymous functions, especially the anonymous functions in[]
that capture the current context variables. When used together withstd::shared_ptr
, it will give the illusion of a dynamic language.