【问题标题】:Why can't boost::hana::overload_t be a member of a class为什么 boost::hana::overload_t 不能成为一个类的成员
【发布时间】:2018-06-30 17:39:36
【问题描述】:

所以我有几个函数,我得到一个神奇的函数对象,它提供重载解决:

void foo1();
void foo2(int);


auto foo_ptr = boost::hana::overload(foo1,foo2);
//Later
foo_ptr(12);  //Both Valid (Yeah!)
foo_ptr();

但是当我这样做时,问题就出现了:

using ptr_t = decltype(foo_ptr);

struct mine
{
    ptr_t ptr;
    mine(ptr_t ptr) : ptr(ptr){}
};


mine m(foo_ptr);

当我尝试编译这段代码时,我得到error: no matching function for call to 'boost::hana::overload_t<void (*)(int)>::overload_t()'

godbolt...上亲自查看。

现在我的问题是:

我是否允许复制这些重载对象(hana 的文档没有说明任何一种方式),如果可以,为什么当我将它作为成员放入类时它会失败?

【问题讨论】:

  • 从错误中,它正在尝试调用默认构造函数。如果您通过引用将ptr 传递给mine 会发生什么?
  • @1201ProgramAlarm 如果我通过 const 引用将 ptr 传递给我的,它出于某种原因可以工作......

标签: c++ c++14 overloading boost-hana


【解决方案1】:

这可以说是 Boost.Hana 中的一个错误。 overload_t的构造函数是:

template <typename F_, typename ...G_>
constexpr explicit overload_t(F_&& f, G_&& ...g)
    : overload_t<F>::type(static_cast<F_&&>(f))
    , overload_t<G...>::type(static_cast<G_&&>(g)...)
{ }

请注意,这些是不受约束的转发引用。当你有一个非常量对象时,这是一个转发引用构造函数比复制构造函数更好匹配的常见问题。简化示例:

struct X {
    X();
    template <typename F> X(F&&); 
    X(X const&) = default;
};

X x1;
X x2(x1); // does *not* call the copy constructor

但是,如果对象是const,那么复制构造函数将是一个更好的匹配。所以简短的解决方法就是这样做:

struct mine
{
    ptr_t ptr;
    mine(ptr_t const& ptr) : ptr(ptr){}
};

现在它编译了。同样,正如 Yakk 所建议的,出于相同的原因,移动而不是复制也可以工作:

struct mine
{
    ptr_t ptr;
    mine(ptr_t ptr) : ptr(std::move(ptr)) {}
};

【讨论】:

  • 我认为移动 ctor 也很诱人;如mine(ptr_t ptr) : ptr(std::move(ptr)){}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-13
  • 2017-12-14
  • 1970-01-01
  • 1970-01-01
  • 2012-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多