包扩展内的整数增量

时间:2019-02-22 14:28:50

标签: c++

我有两个功能rowcolrowcol的包装,应将返回类型打包到元组中。

类似这样的东西

#include <iostream>
#include <tuple>

template<typename T>
T col(size_t i)
{
    return T(i);
}

template<typename ...Ts>
auto row()
{
    size_t i = 0;
    return std::make_tuple(col<Ts>(i++)...); //<-- undefined behaviour
}

int main()
{
    auto m_row = row<int,int,double>(); //should expand to std::make_tuple(col<int>(0),col<int>(1),col<double(2));
    std::cout << "std::get<0>(m_row)-" << std::get<0>(m_row) << std::endl;
    std::cout << "std::get<1>(m_row)-" << std::get<1>(m_row) << std::endl;
    std::cout << "std::get<2>(m_row)-" << std::get<2>(m_row) << std::endl;
    return 0;
}

我的问题是整数i在扩展内必须从0递增到sizeof...(Ts)。我已经考虑了当前类型的索引,但是如果类型不是唯一的,那么这将不起作用。我缺乏其他想法,将不胜感激。

1 个答案:

答案 0 :(得分:0)

使用std::index_sequence_for,我们可以实现一个相对简单的解决方案(但不像我希望的那样简单)。

正如@NathanOliver提到的,它需要一定程度的间接访问,因为我们需要将索引序列通知给辅助函数。现在,顶层函数如下所示:

template <typename... Ts>                                                         
auto row() {                                                                      
    return make_row(std::tuple<Ts...>{},                                          
            std::index_sequence_for<Ts...>{});                                    
}         

因此,helper函数采用默认构造的tuple所请求的类型,以及整数的编译时间序列。

现在助手需要做的就是使用索引序列(0、1,...)构造一个Tuple

template <typename Tuple, std::size_t... Is>                                      
auto make_row(Tuple, std::index_sequence<Is...>) {                                
    return Tuple{ Is... };                                                        
}                                                                                 

最后,要验证这是否符合我们的要求:

int main()                                                                        
{                                                                                 
    auto r = row<int,int,double>();                                               
    static_assert(std::is_same<decltype(r), std::tuple<int, int, double>>::value);
}