Код: Выделить всё
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));
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... ter-to-a-u