C++ 基于其他模板参数推导出模板参数 [英] C++ Deduce template arguments based on other template arguments

查看:27
本文介绍了C++ 基于其他模板参数推导出模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下课程:

template <class T, class U, class V> Foo
{
    ...
};

模板参数有一个不同的映射,所以我可以根据 T 是什么推导出其他模板参数 U 和 V.例如,如果 T 是 double,则 U 和 V 将始终是某些类 D1 和 D2;如果 T 是浮点数,则 U 和 V 将始终是其他某些类 F1 和 F2.

The template parameters have a distinct mapping, so I can deduce the other template arguments U and V based on what T is. For example, if T is double, U and V will always be some classes D1 and D2, and if T is float, U and V will always be some other classes F1 and F2.

考虑到这一点,有没有一种方法可以只传入一个模板参数,并让编译器推断出其他两个参数?

With that in mind, is there a way I can pass in only one template argument, and have the compiler deduce the other two parameters?

我知道简单的答案是也将这些其他类设为模板并将模板参数 T 传递给它们,但我无法将这些类设为模板(它们是由工具自动生成的).

I know the simple answer would be to just make these other classes templated as well and pass the template argument T to them, but I am not able to make these classes templated (they are auto-generated by a tool).

理想情况下,我可以像这样使用 typedef 或 #define:

Ideally I would be able to use typedef or #define like so:

typedef Foo<double> Foo<double, D1, D2>
typedef Foo<float> Foo<float, F1, F2>

但是这些不能编译.我想知道是否有一种方法可以使用模板元编程或模板模板参数来解决这个问题,但我似乎无法理解这些概念,而且我有一种直觉,那里可能有一个更简单的答案.有人有什么想法吗?

However these do not compile. I am wondering if there's a way to use template metaprogramming or template template parameters to solve this issue, but I can't seem to wrap my head those concepts, and I have a gut feeling there's probably an even simpler answer out there. Anybody have any ideas?

推荐答案

Angew 给出的答案向您展示了正确的方法,但没有向您展示如何应对 U 的情况>V 不能推导出,必须由实例化客户端提供.

The answer given by Angew shows you the right approach, but does not show you how to cope with situations where U and V cannot be deduced and must be provided by the instantiating client.

要处理这种情况,您可以为模板参数 UV 分配默认参数:

To handle this case, you could assign default arguments for the template parameters U and 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;
};

这里有一个简单的程序来测试上述解决方案的正确性:

And here is a simple program to test the correctness of the above solution:

#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
}

这篇关于C++ 基于其他模板参数推导出模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆