Можно ли использовать вывод аргументов шаблона класса для класса C из определения одной из функций-членов C? ... или я должен написать свой вспомогательный класс make_c, как в C ++ 03?
Рассмотрим этот минимизированный и упрощенный сценарий, который строит цепочку произвольных функциональных объектов:
template <typename F>
struct node;
template <typename FFwd>
node(FFwd&&) -> node<std::decay_t<FFwd>>;
В классе node хранится функциональный объект, который инициализируется с помощью перенаправления. Мне нужно здесь руководство по дедукции, чтобы decay определить тип объекта функции.
template <typename F>
struct node
{
F _f;
template <typename FFwd>
node(FFwd&& f) : _f{std::forward<FFwd>(f)}
{
}
template <typename FThen>
auto then(FThen&& f_then)
{
return node{[f_then = std::move(f_then)]
{
return f_then();
}};
}
};
После этого я определяю конструктор node и функцию-член продолжения .then, которая возвращает новый узел (его реализация бессмысленна для минимизации размера примера). Если я попытаюсь вызвать _10 _...
auto f = node{[]{ return 0; }}.then([]{ return 0; });
... Я получаю неожиданную ошибку компиляции:
prog.cc: In instantiation of 'node<F>::node(FFwd&&) [with FFwd = node<F>::then(FThen&&) [with FThen = main()::<lambda()>; F = main()::<lambda()>]::<lambda()>; F = main()::<lambda()>]':
prog.cc:27:22: required from 'auto node<F>::then(FThen&&) [with FThen = main()::<lambda()>; F = main()::<lambda()>]'
prog.cc:35:56: required from here
prog.cc:17:46: error: no matching function for call to 'main()::<lambda()>::__lambda1(<brace-enclosed initializer list>)'
node(FFwd&& f) : _f{std::forward<FFwd>(f)}
^
prog.cc:35:20: note: candidate: 'constexpr main()::<lambda()>::<lambda>(const main()::<lambda()>&)'
auto f = node{[]{ return 0; }}.then([]{ return 0; });
^
Это происходит потому, что внутри тела node<F>::then node{...} создает экземпляр с типом *this - он не запускает выведение типа аргумента. Поэтому я вынужден написать:
template <typename FThen>
auto then(FThen&& f_then)
{
auto l = [f_then = std::move(f_then)]{ return f_then(); };
return node<std::decay_t<decltype(l)>>{std::move(l)};
}
... что сводит на нет всю цель руководства по дедукции.
Есть ли способ использовать здесь вывод аргументов шаблона класса без повторения кода или make_node функции?