C++基于其他模板参数推导模板参数
C++ Deduce template arguments based on other template arguments
假设我有以下类:
template <class T, class U, class V> Foo
{
...
};
模板参数有一个不同的映射,所以我可以根据T是什么来推导其他模板参数U和V。例如,如果T是双的,U和V将始终是一些类D1和D2,如果T为float,U和V将始终是其他一些类F1和F2。
考虑到这一点,有没有一种方法可以只传入一个模板参数,并让编译器推导出其他两个参数?
我知道简单的答案是将这些其他类也模板化,并将模板参数T传递给它们,但我无法将这些类模板化(它们是由工具自动生成的)。
理想情况下,我可以像这样使用typedef或#define:
typedef Foo<double> Foo<double, D1, D2>
typedef Foo<float> Foo<float, F1, F2>
但是这些不会编译。我想知道是否有一种方法可以使用模板元编程或模板模板参数来解决这个问题,但我似乎无法理解这些概念,我有一种直觉,可能有一个更简单的答案。有人有什么想法吗?
Angew给出的答案向您展示了正确的方法,但并没有向您展示如何应对U
和V
无法推导且必须由实例化客户端提供的情况。
为了处理这种情况,您可以为模板参数U
和V
:分配默认参数
struct D1 { }; struct D2 { };
struct F1 { }; struct F2 { };
// Primary template
template<typename T>
struct deduce_from
{
};
// Specialization for double: U -> D1, V -> D2
template<>
struct deduce_from<double>
{
typedef D1 U;
typedef D2 V;
};
// Specialization for float: U -> F1, V -> F2
template<>
struct deduce_from<float>
{
typedef F1 U;
typedef F2 V;
};
// Give defaults to U and V: if deduce_from is not specialized for
// the supplied T, and U or V are not explicitly provided, a compilation
// error will occur
template<
typename T,
typename U = typename deduce_from<T>::U,
typename V = typename deduce_from<T>::V
>
struct Foo
{
typedef U typeU;
typedef V typeV;
};
这里有一个简单的程序来测试上述解决方案的正确性:
#include <type_traits>
int main()
{
static_assert(std::is_same<Foo<double>::typeU, D1>::value, "Error!");
static_assert(std::is_same<Foo<double>::typeV, D2>::value, "Error!");
static_assert(std::is_same<Foo<float>::typeU, F1>::value, "Error!");
static_assert(std::is_same<Foo<float>::typeV, F2>::value, "Error!");
// Uncommenting this will give you an ERROR!
// No deduced types for U and V when T is int
/* static_assert(
std::is_same<Foo<int>::typeU, void>::value, "Error!"
); */
static_assert(
std::is_same<Foo<int, bool, char>::typeU, bool>::value, "Error!"
); // OK
static_assert(
std::is_same<Foo<int, bool, char>::typeV, char>::value, "Error!"
); // OK
}
您可以去掉U
和V
,如下所示:
template <typename T>
struct Foo
{
typedef typename deduce_from<T>::U U;
typedef typename deduce_from<T>::V V;
};
其中CCD_ 7封装了推导过程。
相关文章:
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 如何从其他功能C++访问参数?
- C++ 默认参数使用其他参数
- 如何将将参数包作为参数传递给其他模板类的模板类?
- lambda 作为接受其他参数的参数的初始化顺序
- 如何在其他类中使用参数化构造函数制作类的对象?
- 模板参数包如何具有其他尾随参数?
- 在C++单元测试上下文中,抽象基类是否应将其他抽象基类作为函数参数
- 了解'this'或其他参数是否为右值
- 使用其他模板类型参数作为要在函数签名中使用的类型别名声明
- 推断大多数模板对象的参数,但在调用模板函数时对其他对象显式
- 当模板类使用参数包时,如何传递其他模板参数
- 如何将char数组声明为函数参数?或告诉我此代码中还有其他问题?
- 递归回文检查,不使用向量、大小或其他参数
- 将成员函数作为参数传递给其他成员函数 (C++ 11 <function>)
- 依赖于其他模板参数的模板参数
- 传递多个参数的功能,该函数将类包含到其他函数
- 将指针类方法作为参数传递给其他类方法C
- 如果创建支持返回可变参数类型列表的通用模板 API,我应该使用 std::tuple 还是其他东西?
- 如何根据枚举参数返回其他类型