将函数包装器转换为std :: function

时间:2018-10-19 12:26:57

标签: c++ function stl c++14 std-function

我的问题是我有一个函数包装器,其中包含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();

};

1 个答案:

答案 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;可以满足您的需求。