如何检测可变模板中的第一个和最后一个参数
How to detect the first and the last argument in the variadic templates?
如何检测可变模板中的第一个和最后一个参数?
对于第一个参数,这很容易(只是比较sizeof...(T)
与0),但是有没有一种方法来检测最后一个元素?
示例:
#include <iostream>
#include <typeinfo>
template < class... T >
struct A
{
int foo(int k){ return k; };
};
template < class T1, class... T >
struct A< T1, T... >
{
A() :a()
{
std::cout<<"A i="<<sizeof...(T)<<std::endl
<<" a type = " << typeid(T1).name()<<std::endl;
}
int foo(int k){ return anotherA.foo( a.foo(k) ); };
T1 a;
A< T... > anotherA;
};
struct B1
{
B1(){ std::cout<<"b1"<<std::endl; };
int foo(int k){ std::cout<<"b1::foo() k="<<k<<std::endl; return k+1; };
};
struct B2
{
B2(){ std::cout<<"b2"<<std::endl; };
int foo(int k){ std::cout<<"b2::foo() k="<<k<<std::endl; return k+2; };
};
struct B3
{
B3(){ std::cout<<"b3"<<std::endl; };
int foo(int k){ std::cout<<"b3::foo() k="<<k<<std::endl; return k+3; };
};
int main ()
{
A< B3, B2, B1 > a;
std::cout<<"the value is "
<<a.foo(5)
<< std::endl;
}
我不确定这是不是你想要的。但是这里有两个名为first
和last
的实用程序,它们采用可变模板,并分别为第一个和最后一个类型定义类型:
#include <iostream>
#include <typeinfo>
template <class T1, class ...T>
struct first
{
typedef T1 type;
};
template <class T1, class ...T>
struct last
{
typedef typename last<T...>::type type;
};
template <class T1>
struct last<T1>
{
typedef T1 type;
};
template <class ...T>
struct A
{
typedef typename first<T...>::type first;
typedef typename last<T...>::type last;
};
struct B1 {};
struct B2 {};
struct B3 {};
int main()
{
typedef A<B1, B2, B3> T;
std::cout << typeid(T::first).name() << 'n';
std::cout << typeid(T::last).name() << 'n';
}
这是另一组带有方便函数return_type
的代码,您可以使用它来访问可变模板列表中特定索引处的任何类型…然后,您可以调整对return_type
的调用,以便获得第一个和最后一个参数(即,第一个参数将位于0,最后一个参数将位于sizeof...(TypeList)
):
template<typename T>
struct type_id_struct
{
typedef T type;
T object_instance;
};
template<int N, typename... TypeList>
struct reduce {};
template<int N, typename T1, typename... TypeList>
struct reduce<N, T1, TypeList...>
{
typedef typename reduce<N - 1, TypeList... >::type type;
};
template<typename T1, typename... TypeList>
struct reduce<0, T1, TypeList...>
{
typedef T1 type;
};
//convenience function
template<int N, typename... TypeList>
type_id_struct<typename reduce<N, TypeList...>::type> return_type()
{
return type_id_struct<typename reduce<N, TypeList...>::type>();
}
下面是在实际代码中使用方便函数return_type
来确定可变模板中的第n个模板参数的示例:
int main()
{
auto type_returned = return_type<2, int, double, char>();
std::cout << typeid(type_returned.object_instance).name() << std::endl;
return 0;
}
在本例中,由于return_type
的int
模板参数是2
,因此您将得到char
类型作为输出。任何超过2
的数字都将导致溢出,从而创建编译错误而不是运行时错误。如前所述,您可以对其进行调整,以便将其包装在结构中的函数中,该结构允许您使用应用于枚举的sizeof...(TypeList) - 1
访问特定结构实例的可变模板中的类型。例如:
template<typename... TypeList>
struct an_object
{
enum { first = 0, last = (sizeof...(TypeList) - 1) };
template<int N>
auto wrapper() -> decltype(return_type<N, TypeList...>())
{
return return_type<N, TypeList...>();
}
};
//...more code
int main()
{
an_object<int, double, char> a;
auto r_type1 = a.wrapper<an_object<int, double, char>::first>();
std::cout << typeid(r_type1.object_instance).name() << std::endl;
auto r_type2 = a.wrapper<an_object<int, double, char>::last>();
std::cout << typeid(r_type2.object_instance).name() << std::endl;
return 0;
}
相关文章:
- C++部分概念 id:显式模板规范顺序/第一个参数的特殊状态的原因是什么?
- 可变参数模板作为第一个参数
- 如何从第一个参数推断第二个参数类型?
- 候选构造函数(隐式复制构造函数)不可行:第一个参数需要 l 值
- 为什么 std::error_code 构造函数的第一个参数固定为 int
- 如何通过 std::apply 调用具有定义的第一个参数的可变参数模板函数?
- 如何获取指向 qsort 第一个参数的向量中第一项的指针?
- 如何在 Lua 回调中检测可选的第一个参数
- 如何让我的 strchr 函数同时将'const char'数组和'char'数组作为第一个参数?
- 在第一个参数上部分专用化模板
- 模板的C 功能将第一个参数设置为第二个参数为默认参数
- 如何获取指向函数第一个参数的指针
- 我可以使用use_lazy_terminal对获得3个参数懒惰的终端的第一个参数
- C++比较运算符重载中第一个参数为 null 时出现分段错误
- Cc 套接字编程 select() 的第一个参数
- 重载运算符:第一个参数对应左操作数,第二个参数对应右操作数
- 仅初始化c++11元组的第一个参数
- 我可以使用成员函数作为EnumWindows的第一个参数吗
- gdb只接受第一个参数
- 等键在 boost::unordered_multimap 中起作用:查询键是否保证是第一个参数