我的问题是我有一个函数包装器,其中包含std :: function。我想要完成的是能够将其分配给std :: function-像这样:
std::function a = mywrapper;
它可以工作,但是会丢失有关空性的信息-即使包装器类中的std :: function为空,新创建的函数a也不会保留此信息-无法将其强制转换为bool。
如果我的包装器包含一个nullptr(空)std :: function,则函数a在分配后将说它是非空的;即它将布尔转换为true。
有没有办法纠正这种行为?
FunctionWrapper<void()> wrapper;
std::function<void()> std;
std = wrapper;
std::cout << std::boolalpha << bool(std) << std::endl;
这将解析为true。并且应该解析为false。
这是FunctionWrapper类的标题:
template < class >
class FunctionWrapper;
template<class R, class... ArgTypes>
class FunctionWrapper<R(ArgTypes...)>
{
private:
std::function<R(ArgTypes...)> func = nullptr;
public:
FunctionWrapper() = default;
FunctionWrapper(const FunctionWrapper&) = default;
FunctionWrapper(FunctionWrapper&&) = default;
FunctionWrapper(const boost::function<R(ArgTypes...)>&);
FunctionWrapper(boost::function<R(ArgTypes...)>&&);
template<class F> FunctionWrapper(F);
FunctionWrapper& operator=(const FunctionWrapper&) = default;
FunctionWrapper& operator=(FunctionWrapper&&) = default;
FunctionWrapper& operator=(boost::function<R(ArgTypes...)>&);
FunctionWrapper& operator=(boost::function<R(ArgTypes...)>&&);
template<class F> FunctionWrapper& operator=(F&&);
~FunctionWrapper() = default;
//R operator()(ArgTypes...);
operator std::function<R(ArgTypes...)>();
operator boost::function<R(ArgTypes...)>();
explicit operator bool();
};
答案 0 :(得分:2)
我不认为这是可能的,因为随着工作方式的变化,语言没有变化。
编写std = wrapper
时,这就是std.operator=(wrapper)
的语法糖。我们确实在调用该功能。这与初始化不同,我们还考虑在更顶层的†上使用转换函数。因此,基本上,我们有function::operator=
选项:
function& operator=( const function& other ); // #1
function& operator=( function&& other ); // #2
function& operator=( std::nullptr_t ); // #3
template< class F > function& operator=( F&& f ); // #4
template< class F > function& operator=( std::reference_wrapper<F> f ); // #5
#3
和#5
不可行,#4
代表您拥有适当的operator()
和#1
和#2
出于相同的原因以及转换功能的存在。但是#4
是一场精确比赛,而#1
和#2
都不是,因此获胜。句号。
要使#2
胜过#4
(您真正想要的)的唯一方法是使#4
不是候选人。但是,使#4
成为候选人的唯一方法是使wrapper
难以言说。这使得它……根本不是包装器。
因此,您在这里基本上不走运。
†请注意,std::function<void()> std = wrapper;
可以满足您的需求。