【问题标题】:Converting a function wrapper to std::function将函数包装器转换为 std::function
【发布时间】:2018-10-19 12:26:57
【问题描述】:

我的问题是我有一个函数包装器,其中包含一个 std::function 内部。我想要完成的是能够将它分配给 std::function - 就像这样:

std::function a = mywrapper; 

它可以工作,但它会丢失有关过程中空的信息 - 即使我的包装类中的 std::function 为空,新创建的函数 a 也不会保留此信息 - 它不能转换为 bool。

如果我的包装器包含一个 nullptr(空)std::function,则函数 a 在赋值后会说它是非空的;即它将布尔转换为真。

有没有办法纠正这种行为?

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();

};

【问题讨论】:

  • 向我们展示构造函数或转换运算符std::function 使用的主体。
  • template FunctionWrapper::operator std::function() { return func ; }
  • 您的运算符重载负责返回未分配的std::function,而不是包装自身,如果未分配包装的函数。
  • 确定调用了那个方法吗?
  • 我们可以得到minimal reproducible example吗?

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


【解决方案1】:

我认为这是不可能的,除非语言会随着作业的工作方式发生变化。

当您编写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&lt;void()&gt; std = wrapper; 可以满足您的需求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-22
    • 2012-06-25
    • 1970-01-01
    • 2014-12-11
    • 2017-07-08
    • 1970-01-01
    • 2018-11-06
    相关资源
    最近更新 更多