Почему нельзя повысить :: hana :: overload_t быть членом класса - PullRequest
0 голосов
/ 30 июня 2018

Итак, у меня есть пара функций, которые я получаю магический объект функции, который обеспечивает разрешение перегрузки для:

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()'.

Убедитесь сами на Годболт .....

Теперь мой вопрос такой:

Могу ли я скопировать эти объекты перегрузки (документация для hana не говорит так или иначе), и если да, то почему он не работает, когда я помещаю его в класс в качестве члена?

1 Ответ

0 голосов
/ 30 июня 2018

Возможно, это ошибка в 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){}
};

А теперь он компилируется. Аналогично, как предлагает Якк, перемещение вместо копирования также будет работать по той же причине:

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