Is it possible to develop static for loop in c++?

前端 未结 4 1497
情歌与酒
情歌与酒 2020-12-04 13:44

Is it possible for something like this to exist?

template
void deduce_mask(Matrix const &src, int mask[])
{
    //I hope i could b         


        
4条回答
  •  执念已碎
    2020-12-04 14:13

    lego's response, while elegant and awesome, won't compile if you want the index to go into a template - e.g. std::get(some_tuple)

    In case you want to implement this additional feature in the future, the below code will work and should be backwards-compatible with lego's solution (except that I use a static apply method instead of operator()):

    template 
    struct static_for
    {
        template 
        static inline constexpr void apply(Lambda const& f)
        {
            if (First < Last)
            {
                f(std::integral_constant{});
                static_for::apply(f);
            }
        }
    };
    template 
    struct static_for
    {
        template 
        static inline constexpr void apply(Lambda const& f) {}
    };
    

    Now you can do the following:

    static_for<0, Channel>::apply([&](auto i) // Changed from '(int i)'. In general, 'auto' will be a better choice for metaprogramming!
    {            
        // code...
        mask[mapper(0, 1, i)] = src(row - 1, col)[i]; // Notice that this does not change
        std::get(some_tuple); // But here you must get the member .value
        // more code...
    });
    

    Tested in VC++ 2015. I didn't research why this works, but I can only assume that std::integral_constant defines an implicit cast to T using value, but the compiler can't figure out that the implicit cast produces a constexpr, so you have to retrieve the value using i.value, which is a constexpr.

    Addressing @tom's question in the comment If you want to iterate over a parameter pack, you can do the following (same implementation):

    template
    inline constexpr auto foo(const Args&... args)
    {
        static_for<0,sizeof...(Args)>::apply([&](auto N)
        {
            std::cout << std::get(std::make_tuple(args...));
        });
    }
    
    foo(1,"a",2.5); // This does exactly what you think it would do
    

    If std::get(std::make_tuple(args...)) looks ugly, you can create another constexpr function that minimizes the code.

提交回复
热议问题