LINUX.ORG.RU

C++ typedef variadic template

 , ,


1

4

Удобно таскать с каждым темплейтоклассом типы с которыми он специализируется. Но с variadic template-ми что-то не выходит. ЧЯДНТ?

#include <iostream>
#include <functional>

using namespace std;

template <typename... Args>
class Func;

template <typename T, typename... Args>
class Func<T(Args...)> {
public:
	using RetT = T;
	using FunctionT = function<T(Args...)>;
	
	using ArgsT = Args; // <-- error
};

template <typename T>
class FuncBox {
public:
	typename T::FunctionT func;
	
	typename T::RetT call(typename T::ArgsT... args) {
		return func(args...);
	}
};

int main() {
	FuncBox<Func<int(float)>> w;
	
	w.func = [] (float x) -> int {
		cout << x << endl;
		return 4;
	};
	
	w.call(7);
	
	return 0;
}
★★★

Можно кортеж этими типами определять.

O02eg ★★★★★ ()

точку с запятой забыл?

yoghurt ★★★★★ ()
#include <iostream>
#include <functional>

using namespace std;

template <typename... Args>
class Func;

template <typename T, typename... Args>
class Func<T(Args...)> {
public:
    using RetT = T;
    using FunctionT = function<T(Args...)>;
};

template <typename T>
class FuncBox {
public:
    typename T::FunctionT func;
    template<typename... Args>
    typename T::RetT operator()(Args... args) {
      return func(args...);
    }
};

int main() {
  FuncBox<Func<int(float)>> w;
  w.func = [] (float x) -> int {
    cout << x << endl;
    return 4;
  };
  w(7);
  return 0;
}
anonymous ()
Ответ на: комментарий от anonymous

Ого, вот я тупой, вообще это то, что мне нужно. Но, не совсем то, что я описывал.

template <typename... Args>
class StoreArgs {
public:
	using ArgsT = Args;
};

template <typename T>
class TupleBox {
public:
	tuple<T::ArgsT...> t;
};
Kuzy ★★★ ()
Ответ на: комментарий от Kuzy

Ещё можно предложить сделать свою реализацию списков типов. Что-то в духе:

template<typename... Ts> struct list;

template<typename... Ts> struct car;

template<typename T, typename... Ts>
struct car<list<T, Ts...>>
{
  using type = T;
};

template<typename... Ts> struct cdr;

template<typename T, typename... Ts>
struct cdr<list<T, Ts...>>
{
  using type = list<Ts...>;
};

template<unsigned n, typename L> struct nth : nth<n - 1, typename cdr<L>::type> { };
template<unsigned n>             struct nth<n, list<>>;
template<typename L>             struct nth<0, L> : car<L> { };


// usage example:

using l = list<int, char, double>;
template<typename> struct print;

print<car<l>::type> _;
print<cdr<l>::type> _;
print<nth<1, l>::type> _;
print<nth<3, l>::type> _;
Begemoth ★★★★★ ()
Ответ на: комментарий от Begemoth

Прикольно, такой код наверно ведет прямо в ад, если использовать повсеместно рекурсивную раскрутку таких списков.

Kuzy ★★★ ()
Ответ на: комментарий от Kuzy

А стандарт не предусматривает каких-либо иных способов работы с parameter packs произвольной длины. Тот же tuple_element реализован аналогичным образом.

Begemoth ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.