我具有以下结构:
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;
答案 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