c++11之运行期获取tuple元素

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ssss1223ss/article/details/79128453

代码先行

// 运行期以索引获取tuple元素
// 需支持C++11及以上标准的编译器,VS2017 15.5.x、CodeBlocks 16.01 gcc 7.2
// 参考《深入应用C++11:代码优化与工程级应用》p148,祁宇,机械工业出版社,2015年05
template<typename Visit>
void VisitTuple(size_t index, std::tuple<>& t, Visit v) {
}

template<typename T, typename ... Ts, typename Visit>
void VisitTuple(size_t index, std::tuple<T, Ts...>& t, Visit v) {
    if (index >= (1 + sizeof...(Ts))) {
        throw std::invalid_argument("bad index");
    }

    if (index > 0) {
        VisitTuple(index - 1, reinterpret_cast<std::tuple<Ts...>&>(t), v);   // #1 这里是实现关键点
    } else {
        v(std::get<0>(t));
    }
}

// 测试代码
class Vistor {
public:
    template<typename Arg>
    void operator()(Arg&& arg) {
        std::clog << arg << std::endl;
    }
};

int main(int argc, char *argv[]) {
    auto t = std::make_tuple(1, 2, 3, 4, "123");

    for (size_t i = 0; i < std::tuple_size<decltype(t)>::value; ++i) {
        VisitTuple(i, t, Vistor{});
    }
}

实现解析

思路是递归实现,简单易懂。代码中的 #1 出是关键点,也是最不能理解的地方。
怎么样从std::tuple<T, Ts...>中 获取到剔除第一个元素T之后的同内存布局结构呢?代码中使用了reinterpret_cast<std::tuple<Ts...>&>(t)强制转换,初看不可思议。大概是由于tuple采用了类似template<typename T, typename ... Ts> class tuple : public std::tuple<Ts..>{ ... T val_; };的递归继承实现,类型靠前的成员内存布局在后面。

猜你喜欢

转载自blog.csdn.net/ssss1223ss/article/details/79128453
今日推荐