使用模板类型参数列表中的TYPE
use the TYPE from the tempate type argument list
我想使用类模板参数列表中的类型信息。
快速解决方法的工作示例:
struct NoParam {};
template< typename A = NoParam,
typename B = NoParam,
typename C = NoParam,
typename D = NoParam,
typename E = NoParam,
typename F = NoParam >
struct TypeList
{
typedef A T1;
typedef B T2;
typedef C T3;
typedef D T4;
typedef E T5;
typedef F T6;
};
template<typename... Types>
class Application
{
Application()
{
// the actual code will store the created instances in a tuple or map..
std::make_unique< TypeList<Types...>::T1 > ();
std::make_unique< TypeList<Types...>::T2 > ();
std::make_unique< TypeList<Types...>::T3 > ();
std::make_unique< TypeList<Types...>::T4 > ();
std::make_unique< TypeList<Types...>::T5 > ();
std::make_unique< TypeList<Types...>::T6 > ();
}
}
有没有一般的方法…
- 遍历类型并获取类型信息(用于创建实例)
- 没有硬编码,只有6种类型在示例
不要重新发明轮子,您可以使用std::tuple
和std::tuple_element_t
:
template<typename... T>
using TypeList = std::tuple<T...>;
template<int I, typename T>
using Type = std::tuple_element_t<I, T>;
template<typename... Types>
class Application {
Application() {
std::make_unique<Type<0, TypeList<Types...>>> ();
std::make_unique<Type<1, TypeList<Types...>>> ();
// and so on...
}
}
遍历类型现在非常简单。
下面是一个简单的工作示例,向您展示如何做到这一点:
#include <tuple>
#include <functional>
#include <memory>
template<typename... T>
using TypeList = std::tuple<T...>;
template<int I, typename T>
using Type = std::tuple_element_t<I, T>;
template<typename... Types>
class Application {
using MyTypeList = TypeList<Types...>;
template<std::size_t... I>
void iterate(std::index_sequence<I...>) {
// demonstration purposes, here I'm simply creating an object of the i-th type
int _[] = { 0, (Type<I, MyTypeList>{}, 0)... };
(void)_;
}
public:
void iterate() {
iterate(std::make_index_sequence<sizeof...(Types)>{});
}
Application() {
std::make_unique<Type<0, MyTypeList>> ();
std::make_unique<Type<1, MyTypeList>> ();
// and so on...
}
};
int main() {
Application<int, float> app;
app.iterate();
}
注意std::index_sequence
和std::make_index_sequence
从c++ 14开始可用。无论如何,如果你被限制在c++ 11中,你可以在网上找到一些可以使用的实现。
否则,您还可以使用一对递归_sfinae' d_函数来遍历这些类型,这些函数检查是否达到了sizeof...(Types)
。
您可以使用
这样的内容来避免structtypeList
对可变类型进行索引struct noTypeInList
{ };
template <std::size_t, typename ...>
struct typeSel;
template <typename T0, typename ... Ts>
struct typeSel<0U, T0, Ts...>
{ using type = T0; };
template <std::size_t N, typename T0, typename ... Ts>
struct typeSel<N, T0, Ts...>
{ using type = typename typeSel<N-1U, Ts...>::type; };
template <std::size_t N>
struct typeSel<N>
{ using type = noTypeInList; };
std::make_unique< TypeList<Types...>::T1 > ();
成为std::make_unique< typeSel<0, Types...>::type > ();
下面是一个完整的c++ 11示例,以防您想要std::tuple
或std:unique_ptr
#include <tuple>
#include <memory>
struct noTypeInList
{ };
template <std::size_t, typename ...>
struct typeSel;
template <typename T0, typename ... Ts>
struct typeSel<0U, T0, Ts...>
{ using type = T0; };
template <std::size_t N, typename T0, typename ... Ts>
struct typeSel<N, T0, Ts...>
{ using type = typename typeSel<N-1U, Ts...>::type; };
template <std::size_t N>
struct typeSel<N>
{ using type = noTypeInList; };
template <std::size_t ...>
struct range
{ };
template <std::size_t N, std::size_t ... Next>
struct rangeH
{ using type = typename rangeH<N-1U, N-1U, Next ... >::type; };
template <std::size_t ... Next >
struct rangeH<0U, Next ... >
{ using type = range<Next ... >; };
template<typename... Types>
class Application
{
private:
std::tuple<std::unique_ptr<Types>...> tpl;
template <std::size_t ... rng>
Application (const range<rng...> &)
: tpl{std::make_tuple(std::unique_ptr<
typename typeSel<rng, Types...>::type>()...)}
{ }
public:
Application () : Application(typename rangeH<sizeof...(Types)>::type())
{ }
};
int main()
{
Application<int, float, int, std::tuple<double, long>> a;
}
这只是typeSel
的一个例子,因为Application
可以简单地写成
template<typename... Types>
class Application
{
private:
std::tuple<std::unique_ptr<Types>...> tpl;
public:
Application () : tpl{std::make_tuple(std::unique_ptr<Types>()...)}
{ }
};
如果你可以使用c++ 14编译器,你可以使用std::index_sequence
和std::make_index_sequence
(并删除range
和rangeH
), Application
可以变成
template<typename... Types>
class Application
{
private:
std::tuple<std::unique_ptr<Types>...> tpl;
template <std::size_t ... rng>
Application (const std::index_sequence<rng...> &)
: tpl{std::make_tuple(std::unique_ptr<
typename typeSel<rng, Types...>::type>()...)}
{ }
public:
Application () : Application(std::make_index_sequence<sizeof...(Types)>())
{ }
};
最简单、最干净的方法是使用递归模板类:
template<class...> class Application;
template<class T> class Application<T>{
public:
Application()
{
std::make_unique<T> ();
}
};
template<class T,class...Others> class Application<T,Others...>
: public Application<Others...>{
public:
Application():Application<Others...>()
{
std::make_unique<T> ();
}
};
相关文章:
- C++模板/别名 - 模板参数列表中参数 1 处的类型/值不匹配
- 错误:"模板<类_Tp,类_Dp>类 std::unique_ptr"的模板参数列表中参数 1 的类型/值不匹配
- 生成包含给定类型的 N 个参数的可变参数列表的最佳方法?
- 为什么在 ctor 的参数列表中将成员"x"的类型替换为"decltype(x)"会破坏类模板参数推导?
- 没有函数模板的实例"max"与参数列表参数类型匹配(int、int)
- 将参数列表未知的可变参数模板类型定义为 std::map 值类型
- 作为模板类型参数,为什么 type[N] 与其专用版本不匹配----模板<类 T>类 S<T[]>
- 模板参数列表中参数 3 处的类型/值不匹配
- 为什么在函数参数类型中使用模板参数包作为其模板参数列表无法显式指定
- 带有 std::function 的 ADL:可以通过 std::function 参数列表中的类型找到采用 std::function 对象的函数吗?
- 模板参数列表中只有一个类型名称是什么意思?
- 如何将 const 应用于 C++ 中参数列表之外的模板参数类型?
- C - 宏参数中参数列表中的带状类型
- C++如何在模板中推断可调用对象的类型(参数列表和返回值)
- 有人能解释一下特殊的std::函数模板参数列表语法(这个奇怪的类型(Types..))吗
- C++ 可变参数模板和模板模板参数:错误:模板参数列表中参数 1 处的类型/值不匹配
- 如何在变量函数参数列表中检测给定类型的参数的可用性,并在处理完所有参数后采取行动
- std::函数参数列表和类型定义
- 使用模板类型参数列表中的TYPE
- 使用模板类型参数列表重载模板函数