模板参数列表中的部分模板推导

时间:2019-05-20 17:58:30

标签: c++ templates c++17

我具有以下结构:

template<typename T1, typename T2>
struct A {};

template<typename T>
struct B {};

template<typename A, typename B>
struct C {};

,并希望如下使用它们:

C<B<int>, A<double, B<int>>> c;

是否可以推断出A的第二个模板参数,以便我可以像这样使用它?

C<B<int>, A<double>> c;

这应该适用于C的任何模板参数,而不仅适用于特定的模板参数(因此默认参数似乎无效)。

此外,针对可变参数模板的解决方案甚至更好,所以代替

C<B<int>, A<double, B<int>>, A<float, A<double, B<int>>>> c;

像这样的东西会很好:

C<B<int>, A<double>, A<float>> c;

2 个答案:

答案 0 :(得分:3)

有了一些模板元编程的乐趣,我就能够解决两个参数和可变参数情况的问题(尽管以某种狭窄的方式):

// TypeList stuff

template<class... Args>
struct List {
    template<class Arg>
    using Add = List<Args..., Arg>;
};

template<class List> struct TailI;
template<class A, class... Ar> struct TailI<List<A, Ar...>> {
    using type = typename TailI<List<Ar...>>::type;
};

template<class A> struct TailI<List<A>> {
    using type = A;
};


template<class List>
using Tail = typename TailI<List>::type;

template<template<class...> class OP, class List> struct rename_impl;
template<template<class...> class OP, class... ListArgs>
struct rename_impl<OP, List<ListArgs...>> {
    using type = OP<ListArgs...>;
};

template<template<class...> class OP, class List>
using rename = typename rename_impl<OP, List>::type;

// Actual code solving problem at hand    
template<class T1, class T2> struct A{};

template<class... Args> struct C{};

template<class Built, class Next, class... Rest>
struct builder {
    using NewBuilt = typename Built::template Add<A<Next, Tail<Built>>>;
    using type = typename builder<NewBuilt, Rest...>::type;
};

template<class Built, class Next>
struct builder<Built, Next> {
    using NewBuilt = typename Built::template Add<A<Next, Tail<Built>>>;
    using type = rename<C, NewBuilt>;
};


template<class First, class... Rest>
using c_builder = typename builder<List<First>, Rest...>::type;

using t = c_builder<int, double, float>;

// Test driver
#include <utility>

static_assert(std::is_same_v<t, C<int, A<double, int>, A<float, A<double, int>>>>, "");

答案 1 :(得分:2)

对于

的简单情况
template<typename A, typename B> struct C {};

您可以使用助手类为您提供所需的类型。

template<typename T1, typename T2>
struct C_Helper
{
   using type = C<B<T1>, A<T2, B<T1>>>;
};

并使用

using C_Type = typename C_Helper<int, double>::type;
C_Type c;

我还没有考虑过如何扩展以支持可变参数类模板C