我正在研究一个名为group_by
的递归地图类,它对SQL同名进行建模。
例如,gb是一个group_by
对象,它将存储指向按foo
,std::string
和int
键类型分组的char
的指针。顺序。
group_by<foo,std::string,int,char> gb;
group_by
提供了at( I const& key )
访问器方法,可用于查看当前级别的地图。链接at()
调用以检索更深层的地图效果很好。
auto& v = gb.at( k1 ).at( k2 ).at( k3 ).get_vec();
问题
我想创建一个名为at()
的{{1}}替代方案,它可以在一次调用中检索更深层的地图,而无需链接。
at_variadic( Args const& ...args )
但是,我遇到了一些问题。首先,我不知道如何指定返回类型,因为它取决于可变参数。也许以某种方式使用auto& w = gb.at_variadic( k1, k2 );
auto& x = gb.at_variadic( k1, k2, k3 );
?
工作答案
Ecatmur's answer below概述了一种很好的方法。
我不得不玩decltype()
的终端案例以使编译器满意,但下面的代码很大程度上基于Ecatmur的答案,似乎与gcc 4.7.2一起使用。
group_by<>
答案 0 :(得分:4)
链式方法调用本质上是递归的,因此您需要递归地实现at
:
child_type& at( I const& key ) {
return m_map.at( key );
}
template<typename J, typename... Ks>
auto at(const I &i, const J &j, const Ks &...ks)
-> decltype(m_map.at(i).at(j, ks...)) {
return m_map.at(i).at(j, ks...);
}
请注意,由于at
至少需要1个参数,因此可变参数形式至少需要2个参数。这比sizeof...
上的调度更容易实现,并且应该更容易阅读。