当使用 gcc 4.7 和 boost 1.49 时,使用is_assignable
返回的以下表达式:true
typedef boost::function<void()> F;
std::is_assignable<F, std::nullptr_t>::value
但是,此代码无法编译:
boost::function<void()> f;
f = nullptr;
产生这些错误消息:
In file included from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/detail/maybe_include.hpp:13:0,
from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/detail/function_iterate.hpp:14,
from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/preprocessor/iteration/detail/iter/forward1.hpp:47,
from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function.hpp:64,
from ..\main.cpp:8:
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp: In instantiation of 'static void boost::detail::function::void_function_obj_invoker0<FunctionObj, R>::invoke(boost::detail::function::function_buffer&) [with FunctionObj = std::nullptr_t; R = void]':
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:907:60: required from 'void boost::function0<R>::assign_to(Functor) [with Functor = std::nullptr_t; R = void]'
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:722:7: required from 'boost::function0<R>::function0(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = std::nullptr_t; R = void; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]'
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:1042:16: required from 'boost::function<R()>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = std::nullptr_t; R = void; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]'
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:1083:5: required from 'typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, boost::function<R()>&>::type boost::function<R()>::operator=(Functor) [with Functor = std::nullptr_t; R = void; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, boost::function<R()>&>::type = boost::function<void()>&]'
..\main.cpp:172:6: required from here
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:153:11: error: '* f' cannot be used as a function
此外,此表达式返回false
:
typedef boost::function<void()> G;
std::is_assignable<G, decltype(NULL)>::value
但这段代码确实编译:
boost::function<void()> g;
g = NULL;
的结果is_assignable
似乎没有正确反映boost::function
. 我在这里做错了吗?(我无法理解错误消息。)
我认为类型特征应该是确定模板中使用的类的功能的可靠方法。C++11 中提供的类型特征是否与 boost::function 完全不兼容?
为了提供一些背景信息,我一直在从事几个个人项目,以更好地熟悉 C++11 的新特性。对于这个特定的项目,我正在尝试创建一个类来存储可以“停用”的可调用函数。这大致是我想要做的:
template <typename F>
class callable_function
{
public:
callable_function(F func) : func_(func)
{
/* func_ is initially active */
}
void call()
{
if (/* func_ is active */) func_();
}
void deactivate()
{
/* set func_ to deactive */
}
private:
F func_;
};
对于/* func_ is active */
and/* set func_ to deactive */
块,我想提供两种不同的实现,在编译时根据F
. 如果nullptr
可以分配给func_
并且func_
可以在布尔上下文中使用,那么我想使用以下内容(这是为内置函数指针和选择的内容std::function
):
template <typename F>
class callable_function
{
public:
callable_function(F func) : func_(func) {}
void call()
{
if (func_) func_();
}
void deactivate()
{
func_ = nullptr;
}
private:
F func_;
};
如果nullptr
不能分配给func_
,那么我想在存储“活动”状态的类中存储一个额外的布尔值。为仿函数和 lambda 函数选择此实现:
template <typename F>
class callable_function
{
public:
callable_function(F func) : func_(func), active_(true) {}
void call()
{
if (active_) func_();
}
void deactivate()
{
active_ = false;
}
private:
F func_;
bool active_;
};
由于nullptr
目前无法分配给boost::function
,我希望选择第二个实现。但是,由于is_assignable
is 返回true
forboost::function
和nullptr
,因此选择了第一个实现,这会导致deactivate
函数中出现编译错误。