如何编写一个替换链式方法调用的可变方法?

时间:2013-02-18 11:02:23

标签: c++ templates c++11 variadic-functions

我正在研究一个名为group_by的递归地图类,它对SQL同名进行建模。

例如,gb是一个group_by对象,它将存储指向按foostd::stringint键类型分组的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<>

1 个答案:

答案 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...上的调度更容易实现,并且应该更容易阅读。