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

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Передайте функцию вариального шаблона, принимая универсальные ссылки в качестве указателя на утилиту

Сообщение Anonymous »

У меня есть проблема с попыткой факторизации двух функций утилиты, каждая из которых вызывает заданную функцию «жестко кодировать», в одну утилиту с вызовом Functor. Это означает, что у меня есть возможность факторинг с использованием объекта функции более высокого порядка.

Код: Выделить всё

void Util1() { A(); }
void Util2() { B(); }

void Client()
{
Util1();
Util2();
}
< /code>
into: < /p>
template< typename F >
void Util(F&& f) { f(); }

void Client()
{
Util(&A);
Util(&B);
}
< /code>
Но проблема заключается в том, что a () и b () фактически: < /p>
template< typename... Args >
constexpr void A(Args&&... args)
{
// blah
}
Так что, очевидно, я получаю такие вещи, как не соответствующая перегруженная функция, найденная
Но я знаю 2 трюки: дайте полный список шаблонов или Cast . Но вот где проблема поражает стену. Args && Часть списка параметров в A создает тип с Arguments && везде. Я полагаю, что универсальные справочные материалы основаны на обрушении ссылок в зависимости от выведенных типов из выражения сайта вызовов. Я не могу найти способ получить указатель функции на A, который имеет типы списков параметров, которые эквивалентно сжаваются с естественным выражением сайта вызовов. PrettyPrint-Override ">

Код: Выделить всё

#include 
#include 
using std::size_t;

// utility, don't mind it
template< typename... > struct FirstTypeExtractor;
template< typename First, typename... Rest >
struct FirstTypeExtractor{ using type = First; };
template< typename... Vs >
using FirstTypeExtractor_t = typename FirstTypeExtractor::type;

// tag dispatch system for implementations
struct DefaultImplTag {};

template< typename T >
struct ImplTag
{
using type = DefaultImplTag;
};

template< typename T > // shortcut to avoid 'typename' verbosity
using ImplTag_t = typename ImplTag< typename std::decay::type >::type;

// main API
template< typename... Args >
constexpr void Foo(Args&&... args)
{
return FooImpl(ImplTag_t< FirstTypeExtractor_t >{}, std::forward(args)...);
}

constexpr void Foo(){} // terminator

// default impl
template
constexpr void FooImpl(DefaultImplTag, First&& first, Rest&&... rest)
{
Foo(std::forward(rest)...);
}

// similar things for Bar family
//...

// tuple version

struct TupleImplTag {};

/// Specialize ImplTag for std::tuple
template 
struct ImplTag< std::tuple >
{
using type = TupleImplTag;
};

// generic implementation of the utility for tuples:
template
constexpr void MapFToAllTupleElements(F&& functor, const Tuple& tup, std::index_sequence)
{
return functor(std::get(tup)...);
}
// creates:
// :75:20: error: rvalue reference to type 'const char *const' cannot bind to lvalue of type 'const __tuple_element_t' (aka 'const char *const')
//    75 |     return functor(std::get(tup)...);
//       |                    ^~~~~~~~~~~~~~~~~
// :94:12: note: in instantiation of function template specialization 'MapFToAllTupleElements' requested here
//    94 |     return MapFToAllTupleElements(&Foo, tup, std::index_sequence_for{});

// ### hardcoded call utility. this works obviously but is not DRY ###
// template
// constexpr void FooAllTupleElements(const Tuple& tup, std::index_sequence)
// {
//     return Foo(std::get(tup)...);
// }

// template
// constexpr void BarAllTupleElements(const Tuple& tup, std::index_sequence)
// {
//     return Bar(std::get(tup)...);
// }

template
constexpr void FooImpl(TupleImplTag, const std::tuple& tup)
{
return MapFToAllTupleElements(&Foo, tup, std::index_sequence_for{});  // wanted
//return FooAllTupleElements(tup, std::index_sequence_for{});  // ok but sad
}

template
constexpr void BarImpl(TupleImplTag, const std::tuple& tup)
{
// same for Bar
}

int main()
{
Foo(std::make_tuple("str", 'c'));

//Bar(std::make_tuple(true, 0));
}
godbolt link

Подробнее здесь: https://stackoverflow.com/questions/797 ... ter-to-a-u
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»