如何使用可变参数模板转发类型和值模板参数
How do I use variadic templates to forward both type and value template parameters?
假设我们有 3 种类型(S1、S2 和 S3):
//type 1 (good type)
template<typename T1, typename T2, typename T3>
struct S1{};
//type 2 (good type)
template<typename T1, typename T2, typename T3, int T4>
struct S2{};
//type 3 (bad type)
template<typename T1, typename T2, typename T3>
struct S3{};
//any other type is also a "bad type"
我们要创建一个类型特征来确定类型是 S1 还是 S2。
为简洁起见,我们使用可变参数模板,因为 T# 的详细信息不是很重要:
//a type trait to determine if a type is either "type 1" or "type 2"
//We expect ::value to be true if we can match either type.
//false otherwise.
//*ignore cv-qualifier related details
template <typename T> struct test:std::false_type{};
template <typename... Args> struct test<S1<Args...>>:std::true_type{};
template <typename... Args> struct test<S2<Args...>>:std::true_type{};
如果我们要测试这种类型的特征,我们可以看到它不适用于 S2:
std::cout << std::boolalpha;
std::cout << test<S1<int,int,int>>::value << 'n';
std::cout << test<S2<int,int,int,5>>::value << 'n';
std::cout << test<S3<int,int,int>>::value << 'n';
指纹:
true
false
false
它不适用于 S2,因为已经定义了其中一个模板类型(在这种情况下,T4 已经是一个 int)。
是否可以使用可变参数模板以这种方式匹配所有模板类型?
无论它们是类型名称还是实际类型。
template <class A0,class A1, class A2, int x> struct test<S2<A0,A1,A2,x>>:std::true_type{};
通常,使用非类型模板参数进行元元编程是一种痛苦。
如果你经常这样做,请考虑使用像integral_constant
之类的东西:将值作为类型而不是值传递。 您甚至可以将模板作为类型传递。
这是一个解决方案,可以提供您想要的输出,而无需重新设计 S2:
#include <iostream>
#include <type_traits>
template<typename T1, typename T2, typename T3>
struct S1{};
//type 2 (good type)
template<typename T1, typename T2, typename T3, int T4>
struct S2{};
//type 3 (bad type)
template<typename T1, typename T2, typename T3>
struct S3{};
template <typename T> struct test : std::false_type{};
template <typename... Args> struct test<S1<Args...>> : std::true_type{};
template <template <typename, typename, typename, int> class P, typename A, typename B, typename C, int N>
struct test<P<A,B,C,N>> : std::conditional<
std::is_same<P<A,B,C,N>, S2<A,B,C,N>>::value,
std::true_type,
std::false_type
>::type {};
template <typename T1, typename T2, typename T3, int T4> struct S2Wannabe {};
int main() {
std::cout << std::boolalpha;
std::cout << test<S1<int,int,int>>::value << 'n'; // true
std::cout << test<S2<int,int,int,5>>::value << 'n'; // true
std::cout << test<S3<int,int,int>>::value << 'n'; // false
std::cout << test<S2Wannabe<int,int,int,5>>::value << 'n'; // false
}
但是重新设计 S2 可能会更容易地解决您的问题。
相关文章:
- 扩展C++生成的代码的模板参数类型名称
- 如何在 c++ 中定义接受不同参数类型的函数向量?
- 在 C++ 中运行时调用模板时,是否可以切换模板的参数类型?
- 将函数参数类型声明为 auto
- 将函数的参数 - 签名从使用 'std::function<T>' 转换为模板参数类型
- 在 C++17 中调用具有不同参数类型的构造函数
- 具有先前参数类型匹配的参数包
- 我想知道为什么"std::unique_ptr<int> foo(新 int)"是合法的,因为"std::<int>unique_ptr"要求输入参数类型应该是"int"?
- 将可变参数类型列表的扩展打包为复杂类型的初始值设定项列表 - 合法吗?
- MSVC 错误:4 个重载中的任何一个都无法转换所有参数类型
- 使用constexpr + auto作为返回和参数类型的奇怪类型推导
- 如何从第一个参数推断第二个参数类型?
- C++模板函数中,指定回调函子/lambda 的参数类型,同时仍允许内联?
- 如何用不同的参数类型和数字回调函数
- C++stoi:这两个重载都无法转换所有参数类型
- 为什么std::{container}::template不能推导其参数类型
- 为模板参数类型中的新对象分配内存
- 为指向成员模板参数的指针推导额外模板参数类型的紧凑方式
- 使用std::conditional中的模板来确定函数参数类型
- C++中的短参数类型