整齐地链接由可变 class args 指定的依赖元组引用

Neatly linking dependency tuple references specified by variadic class args

给定以下 class 结构,其中我们拥有许多不同的 classes C#,每个都具有传递到多个分类帐中的唯一数据 L<C#>,以及拥有许多 classes S#,每个都取决于 C# 下 classes 的某个子集,我建立了一个包含所有分类帐的元组在经理 class E.

// Dependency classes
struct C {};
struct C1 : C {};
struct C2 : C {};

// Dependency data ledger
template <class T>
class L {};

// Dependency user
template <class... Cs>
struct S {
  using Deps = std::tuple<Cs...>;
  using DepRefs = std::tuple<L<Cs>&...>;
};
struct S1 : S<C1> {};
struct S2 : S<C1, C2> {};

// Manager
template <class... Ss>
class E;
template <class... Ss>
class E : public E<all_deps_no_duplicates<Ss...>, Ss...> {};
template <class... Cs, class... Ss>
class E<std::tuple<Cs...>, Ss...> {
  std::tuple<L<Cs>...> DepsData;
  std::tuple<typename Ss::DepsRefs...> DepsRefs; // Problem instantiation.
};

// Usage
int main() { E<S1, S2> e; };

然后存在哪些优雅的解决方案来建立包含对每个依赖项用户的依赖项分类帐的引用的辅助元组?依赖分类帐元组中没有重复项,每个依赖项有一个分类帐,每个依赖项可能有许多依赖项用户。例如,在给定的代码中,我希望管理器 class E 中的第一个和第二个元组分别包含:

DepsData:

std::tuple<
  L<C1>(), // 1st element: a ledger for C1
  L<C2>()  // 2nd element: a ledger for C2
>

DepsRefs:

std::tuple<
  std::tuple<L<C1>&>,         // tuple containing reference to DepsData 1st element
  std::tuple<L<C1>&, L<C2>&>  // tuple containing reference to DepsData 1st and 2nd elements
>

DepsRefs 中的两个 L<C1>& 引用引用了 DepsData 中指定的同一分类帐。

所以专注于引用初始化,你可以做这样的事情:

template <typename T> struct Tag{};

template <typename... Ts, typename Tuple>
std::tuple<L<Ts>&...> make_ref_tuple(Tag<std::tuple<L<Ts>&...>>, Tuple& tuple)
{
    return {std::get<L<Ts>>(tuple)...};
}

template <class... Cs, class... Ss>
class E<std::tuple<Cs...>, Ss...> {
  std::tuple<L<Cs>...> DepsData;
  std::tuple<typename Ss::DepsRefs...> DepsRefs =
     { make_ref_tuple(Tag<typename Ss::DepsRefs>{}, DepsData)... };
};

Demo