为什么 boost::hana::overload_t 不能成为 class 的成员
Why can't boost::hana::overload_t be a member of a class
所以我有几个函数,我得到了一个魔法函数对象,它提供了重载解析:
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 的文档没有说明任何一种方式),如果可以,为什么当我将它作为成员放入 class 时它会失败?
这可以说是 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)) {}
};
所以我有几个函数,我得到了一个魔法函数对象,它提供了重载解析:
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 的文档没有说明任何一种方式),如果可以,为什么当我将它作为成员放入 class 时它会失败?
这可以说是 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)) {}
};