Применение (своего рода мета) функции к последовательности типов

У меня есть функция:

template <typename T> std::string foo();

о котором вы могли бы подумать, что принимаете тип в качестве ввода и производите строку.

У меня также есть либо пакет параметров, либо кортеж, как вам удобнее; Предположим, это

using std::tuple<MyParameters...> my_types;

Теперь я хочу призвать foo<T> на каждый тип T в пакете или в определении типа кортежа, в последовательности.

Я понимаю, что, вероятно, смогу получить это, используя библиотеку, такую ​​как Boost MPL или Boost Hana, но я не хочу вставлять все это в мой код, и мне было интересно, можно ли «захватить» принцип этого в чем-то кратким ,

Заметки:

  • Бонусные баллы, если вы могли бы предоставить ответ, который работает с общими лямбда-выражениями вместо шаблонной функции.
  • Ответ должен быть C ++ 14, а не C ++ 17.

0

Решение

ИМХО, для такого рода вещей нужна частичная специализация.
Так что структура / классы, не функции.

Так что, если вы можете требовать работы к методу переменной структуры bar, ты можешь написать foo() вызов метода в bar ( operator()по примеру) следующим образом

template <typename T>
std::string foo ()
{ return bar<T>()(); }

Ниже приведен полный рабочий (я не знаю, достаточно ли «краткий») пример; это C ++ 11, если я не ошибаюсь.

#include <tuple>
#include <complex>
#include <iostream>

template <typename ...>
struct bar;

template <typename T0, typename ... Ts>
struct bar<T0, Ts...>
{
std::string operator() ()
{ return "type; " + bar<Ts...>()(); }
};

template <template <typename ...> class C,
typename ... Ts1, typename ... Ts2>
struct bar<C<Ts1...>, Ts2...>
{
std::string operator() ()
{ return "type container; " + bar<Ts1...>()() + bar<Ts2...>()(); }
};

template <>
struct bar<>
{ std::string operator() () { return {}; } };

template <typename T>
std::string foo ()
{ return bar<T>()(); }

int main ()
{
std::cout << foo<int>() << std::endl;
std::cout << foo<std::tuple<int, long, short, std::tuple<long, int>>>()
<< std::endl;
std::cout << foo<std::complex<double>>() << std::endl;
}

с .: мне не ясно, что вы имеете в виду под «ответом, который работает с общими лямбда-выражениями вместо шаблонной функции».

Можете ли вы показать пример использования?

1

Другие решения

Комментарий @ T.C.

#include <array>
#include <string>
#include <iostream>

template <typename T> std::string foo() {
return std::to_string(sizeof(T));
}

template <typename... Ts>
std::array<std::string, sizeof...(Ts)> multi_foo() {
return { foo<Ts>()... };
}

int main() {
auto size_strings = multi_foo<char, short, int, long, long long>();
for(const auto& s : size_strings) { std::cout << s << ' '; };
std::cout << std::endl;
}

Смотрите также живая версия — производя ожидаемый результат:

1 2 4 8 8

на машине x86_64.

0

По вопросам рекламы [email protected]