Alternative to integer_sequence trick

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite












I hate working with std::integer_sequence. Each time I want to write a function foo I have to write an another function foo_impl where the actual stuff is happening. Therefore I'm polluting the space with additional function and the code is kind of scattered around. I came up with an alternative and I would love to know your opinion.




Let's define integral_sequence<N>. Here we use the damned std::integer_sequence for the last time!



template <std::size_t... I>
constexpr auto integral_sequence_impl(std::index_sequence<I...>)
return std::make_tuple(std::integral_constant<std::size_t, I>...);


template <int N>
auto integral_sequence = integral_sequence_impl(std::make_index_sequence<N>);


To demonstrate its use, lets redo the example code for std::integral_sequence:



// Convert array into a tuple
template <typename T, std::size_t N>
decltype(auto) a2t(const std::array<T, N> &a)
auto impl = [&](auto... I) return std::make_tuple(a[I]...); ;

return std::apply(impl, integral_sequence<N>);


// pretty-print a tuple
template <class Ch, class Tr, class... Args>
decltype(auto) operator<<(std::basic_ostream<Ch, Tr> &os,
const std::tuple<Args...> & t)

auto impl = [&](auto... I)
((os << (I == 0 ? "" : ", ") << std::get<I>(t)), ...);
;

os << "(";
std::apply(impl, integral_sequence<sizeof...(Args)>);
return os << ")";


int main()
std::array<int, 4> array = 1, 2, 3, 4;

// convert an array into a tuple
auto tuple = a2t(array);
static_assert(
std::is_same<decltype(tuple), std::tuple<int, int, int, int>>::value, "");

// print it to cout
std::cout << tuple << 'n';



The trick with integral_sequence is kind of the same as with integer_sequence. However, because it can be used with generic lambda you do not have to define an extra function, all code can be neatly together and it reduces visual clutter.



So what do you think? Are there any disadvantages?



The only problems I can see now is that it is only c++17 and integral_sequence<400> takes really long time to compile.







share|improve this question



























    up vote
    3
    down vote

    favorite












    I hate working with std::integer_sequence. Each time I want to write a function foo I have to write an another function foo_impl where the actual stuff is happening. Therefore I'm polluting the space with additional function and the code is kind of scattered around. I came up with an alternative and I would love to know your opinion.




    Let's define integral_sequence<N>. Here we use the damned std::integer_sequence for the last time!



    template <std::size_t... I>
    constexpr auto integral_sequence_impl(std::index_sequence<I...>)
    return std::make_tuple(std::integral_constant<std::size_t, I>...);


    template <int N>
    auto integral_sequence = integral_sequence_impl(std::make_index_sequence<N>);


    To demonstrate its use, lets redo the example code for std::integral_sequence:



    // Convert array into a tuple
    template <typename T, std::size_t N>
    decltype(auto) a2t(const std::array<T, N> &a)
    auto impl = [&](auto... I) return std::make_tuple(a[I]...); ;

    return std::apply(impl, integral_sequence<N>);


    // pretty-print a tuple
    template <class Ch, class Tr, class... Args>
    decltype(auto) operator<<(std::basic_ostream<Ch, Tr> &os,
    const std::tuple<Args...> & t)

    auto impl = [&](auto... I)
    ((os << (I == 0 ? "" : ", ") << std::get<I>(t)), ...);
    ;

    os << "(";
    std::apply(impl, integral_sequence<sizeof...(Args)>);
    return os << ")";


    int main()
    std::array<int, 4> array = 1, 2, 3, 4;

    // convert an array into a tuple
    auto tuple = a2t(array);
    static_assert(
    std::is_same<decltype(tuple), std::tuple<int, int, int, int>>::value, "");

    // print it to cout
    std::cout << tuple << 'n';



    The trick with integral_sequence is kind of the same as with integer_sequence. However, because it can be used with generic lambda you do not have to define an extra function, all code can be neatly together and it reduces visual clutter.



    So what do you think? Are there any disadvantages?



    The only problems I can see now is that it is only c++17 and integral_sequence<400> takes really long time to compile.







    share|improve this question























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      I hate working with std::integer_sequence. Each time I want to write a function foo I have to write an another function foo_impl where the actual stuff is happening. Therefore I'm polluting the space with additional function and the code is kind of scattered around. I came up with an alternative and I would love to know your opinion.




      Let's define integral_sequence<N>. Here we use the damned std::integer_sequence for the last time!



      template <std::size_t... I>
      constexpr auto integral_sequence_impl(std::index_sequence<I...>)
      return std::make_tuple(std::integral_constant<std::size_t, I>...);


      template <int N>
      auto integral_sequence = integral_sequence_impl(std::make_index_sequence<N>);


      To demonstrate its use, lets redo the example code for std::integral_sequence:



      // Convert array into a tuple
      template <typename T, std::size_t N>
      decltype(auto) a2t(const std::array<T, N> &a)
      auto impl = [&](auto... I) return std::make_tuple(a[I]...); ;

      return std::apply(impl, integral_sequence<N>);


      // pretty-print a tuple
      template <class Ch, class Tr, class... Args>
      decltype(auto) operator<<(std::basic_ostream<Ch, Tr> &os,
      const std::tuple<Args...> & t)

      auto impl = [&](auto... I)
      ((os << (I == 0 ? "" : ", ") << std::get<I>(t)), ...);
      ;

      os << "(";
      std::apply(impl, integral_sequence<sizeof...(Args)>);
      return os << ")";


      int main()
      std::array<int, 4> array = 1, 2, 3, 4;

      // convert an array into a tuple
      auto tuple = a2t(array);
      static_assert(
      std::is_same<decltype(tuple), std::tuple<int, int, int, int>>::value, "");

      // print it to cout
      std::cout << tuple << 'n';



      The trick with integral_sequence is kind of the same as with integer_sequence. However, because it can be used with generic lambda you do not have to define an extra function, all code can be neatly together and it reduces visual clutter.



      So what do you think? Are there any disadvantages?



      The only problems I can see now is that it is only c++17 and integral_sequence<400> takes really long time to compile.







      share|improve this question













      I hate working with std::integer_sequence. Each time I want to write a function foo I have to write an another function foo_impl where the actual stuff is happening. Therefore I'm polluting the space with additional function and the code is kind of scattered around. I came up with an alternative and I would love to know your opinion.




      Let's define integral_sequence<N>. Here we use the damned std::integer_sequence for the last time!



      template <std::size_t... I>
      constexpr auto integral_sequence_impl(std::index_sequence<I...>)
      return std::make_tuple(std::integral_constant<std::size_t, I>...);


      template <int N>
      auto integral_sequence = integral_sequence_impl(std::make_index_sequence<N>);


      To demonstrate its use, lets redo the example code for std::integral_sequence:



      // Convert array into a tuple
      template <typename T, std::size_t N>
      decltype(auto) a2t(const std::array<T, N> &a)
      auto impl = [&](auto... I) return std::make_tuple(a[I]...); ;

      return std::apply(impl, integral_sequence<N>);


      // pretty-print a tuple
      template <class Ch, class Tr, class... Args>
      decltype(auto) operator<<(std::basic_ostream<Ch, Tr> &os,
      const std::tuple<Args...> & t)

      auto impl = [&](auto... I)
      ((os << (I == 0 ? "" : ", ") << std::get<I>(t)), ...);
      ;

      os << "(";
      std::apply(impl, integral_sequence<sizeof...(Args)>);
      return os << ")";


      int main()
      std::array<int, 4> array = 1, 2, 3, 4;

      // convert an array into a tuple
      auto tuple = a2t(array);
      static_assert(
      std::is_same<decltype(tuple), std::tuple<int, int, int, int>>::value, "");

      // print it to cout
      std::cout << tuple << 'n';



      The trick with integral_sequence is kind of the same as with integer_sequence. However, because it can be used with generic lambda you do not have to define an extra function, all code can be neatly together and it reduces visual clutter.



      So what do you think? Are there any disadvantages?



      The only problems I can see now is that it is only c++17 and integral_sequence<400> takes really long time to compile.









      share|improve this question












      share|improve this question




      share|improve this question








      edited Apr 3 at 22:28









      Quuxplusone

      9,82511451




      9,82511451









      asked Apr 3 at 21:50









      tom

      1364




      1364




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          5
          down vote













          Looks good to me! I mean, I'm not likely to convert to it because of its heavyweightness — you noted its use of std::apply, but it also pulls in all of <tuple> every time you use it, too. Also, it's arguably coincidental that your expressions a[I] and std::get<I>(t) work in this context, since what's actually happening in both cases is an implicit conversion from std::integral_constant<size_t, K> to size_t. In some contexts, the user might need to explicitly cast int(I) or whatever.



          You could remove the std::apply dependency and simplify the user's job at the same time by writing a helper function apply_to_sequence<N>(lambda), as in:



          // Convert array into a tuple
          template <typename T, std::size_t N>
          auto a2t(const std::array<T, N>& a)
          return apply_to_sequence<N>([&](auto... Is)
          return std::make_tuple(a[Is]...);
          );



          (Oh yeah, I think your use of decltype(auto) in this function was bogus and could result in dangling references. Certainly auto would be fine, so I recommend it.)



          // pretty-print a tuple
          template <class Ch, class Tr, class... Args>
          auto& operator<<(std::basic_ostream<Ch, Tr>& os,
          const std::tuple<Args...>& t)

          os << "(";
          apply_to_sequence<sizeof...(Args)>([&](auto... Is)
          ((os << (Is == 0 ? "" : ", ") << std::get<Is>(t)), ...);
          );
          return os << ")";



          Writing apply_to_sequence from scratch is left as an exercise for the reader, but the trivial C++17 implementation is just this:



          template<size_t N, class F>
          decltype(auto) apply_to_sequence(const F& fn)
          return std::apply(fn, integral_sequence<N>);



          Having hidden the implementation details apply and integral_sequence from the reader, we are now free — if we so desire — to replace them with things that are



          • faster

          • C++14-compatible


          • <tuple>-free

          One stylistic note: I prefer to name my parameter packs with plurals, so, singular auto I but plural auto... Is. That's the logic behind my renaming above.






          share|improve this answer





















          • About the decltype(auto), I took the code straight from cppreference.com is the use there bogus too? Or is it specific to my code?
            – tom
            Apr 4 at 6:25










          • @tom about the decltype(auto): Hmm, looks like it's non-bogus specifically because your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case. But I still strongly recommend that you never use decltype(auto) in C++ until you can explain the behavior of this little snippet. (Which, in practice, means: never use it, ever. ;)) — P.S. I adjusted the cppreference page. ;)
            – Quuxplusone
            Apr 4 at 6:46











          • @Quuxplusone, or one can grab Effective Modern C++ :) I got a little bit confused about your comment on decltype(auto), but now I see that it applies only to your code.
            – Incomputable
            Apr 6 at 6:45










          • @Incomputable: I'm sure we're both being too vague. :) When I said "your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case", I was talking about Tom's code i.e. cppreference's code, and the first Wandbox link was an example demonstrating that concept in isolation. The word "this" in "this little snippet" was indeed intended to refer to the second Wandbox link itself.
            – Quuxplusone
            Apr 6 at 19:26










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191203%2falternative-to-integer-sequence-trick%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          5
          down vote













          Looks good to me! I mean, I'm not likely to convert to it because of its heavyweightness — you noted its use of std::apply, but it also pulls in all of <tuple> every time you use it, too. Also, it's arguably coincidental that your expressions a[I] and std::get<I>(t) work in this context, since what's actually happening in both cases is an implicit conversion from std::integral_constant<size_t, K> to size_t. In some contexts, the user might need to explicitly cast int(I) or whatever.



          You could remove the std::apply dependency and simplify the user's job at the same time by writing a helper function apply_to_sequence<N>(lambda), as in:



          // Convert array into a tuple
          template <typename T, std::size_t N>
          auto a2t(const std::array<T, N>& a)
          return apply_to_sequence<N>([&](auto... Is)
          return std::make_tuple(a[Is]...);
          );



          (Oh yeah, I think your use of decltype(auto) in this function was bogus and could result in dangling references. Certainly auto would be fine, so I recommend it.)



          // pretty-print a tuple
          template <class Ch, class Tr, class... Args>
          auto& operator<<(std::basic_ostream<Ch, Tr>& os,
          const std::tuple<Args...>& t)

          os << "(";
          apply_to_sequence<sizeof...(Args)>([&](auto... Is)
          ((os << (Is == 0 ? "" : ", ") << std::get<Is>(t)), ...);
          );
          return os << ")";



          Writing apply_to_sequence from scratch is left as an exercise for the reader, but the trivial C++17 implementation is just this:



          template<size_t N, class F>
          decltype(auto) apply_to_sequence(const F& fn)
          return std::apply(fn, integral_sequence<N>);



          Having hidden the implementation details apply and integral_sequence from the reader, we are now free — if we so desire — to replace them with things that are



          • faster

          • C++14-compatible


          • <tuple>-free

          One stylistic note: I prefer to name my parameter packs with plurals, so, singular auto I but plural auto... Is. That's the logic behind my renaming above.






          share|improve this answer





















          • About the decltype(auto), I took the code straight from cppreference.com is the use there bogus too? Or is it specific to my code?
            – tom
            Apr 4 at 6:25










          • @tom about the decltype(auto): Hmm, looks like it's non-bogus specifically because your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case. But I still strongly recommend that you never use decltype(auto) in C++ until you can explain the behavior of this little snippet. (Which, in practice, means: never use it, ever. ;)) — P.S. I adjusted the cppreference page. ;)
            – Quuxplusone
            Apr 4 at 6:46











          • @Quuxplusone, or one can grab Effective Modern C++ :) I got a little bit confused about your comment on decltype(auto), but now I see that it applies only to your code.
            – Incomputable
            Apr 6 at 6:45










          • @Incomputable: I'm sure we're both being too vague. :) When I said "your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case", I was talking about Tom's code i.e. cppreference's code, and the first Wandbox link was an example demonstrating that concept in isolation. The word "this" in "this little snippet" was indeed intended to refer to the second Wandbox link itself.
            – Quuxplusone
            Apr 6 at 19:26














          up vote
          5
          down vote













          Looks good to me! I mean, I'm not likely to convert to it because of its heavyweightness — you noted its use of std::apply, but it also pulls in all of <tuple> every time you use it, too. Also, it's arguably coincidental that your expressions a[I] and std::get<I>(t) work in this context, since what's actually happening in both cases is an implicit conversion from std::integral_constant<size_t, K> to size_t. In some contexts, the user might need to explicitly cast int(I) or whatever.



          You could remove the std::apply dependency and simplify the user's job at the same time by writing a helper function apply_to_sequence<N>(lambda), as in:



          // Convert array into a tuple
          template <typename T, std::size_t N>
          auto a2t(const std::array<T, N>& a)
          return apply_to_sequence<N>([&](auto... Is)
          return std::make_tuple(a[Is]...);
          );



          (Oh yeah, I think your use of decltype(auto) in this function was bogus and could result in dangling references. Certainly auto would be fine, so I recommend it.)



          // pretty-print a tuple
          template <class Ch, class Tr, class... Args>
          auto& operator<<(std::basic_ostream<Ch, Tr>& os,
          const std::tuple<Args...>& t)

          os << "(";
          apply_to_sequence<sizeof...(Args)>([&](auto... Is)
          ((os << (Is == 0 ? "" : ", ") << std::get<Is>(t)), ...);
          );
          return os << ")";



          Writing apply_to_sequence from scratch is left as an exercise for the reader, but the trivial C++17 implementation is just this:



          template<size_t N, class F>
          decltype(auto) apply_to_sequence(const F& fn)
          return std::apply(fn, integral_sequence<N>);



          Having hidden the implementation details apply and integral_sequence from the reader, we are now free — if we so desire — to replace them with things that are



          • faster

          • C++14-compatible


          • <tuple>-free

          One stylistic note: I prefer to name my parameter packs with plurals, so, singular auto I but plural auto... Is. That's the logic behind my renaming above.






          share|improve this answer





















          • About the decltype(auto), I took the code straight from cppreference.com is the use there bogus too? Or is it specific to my code?
            – tom
            Apr 4 at 6:25










          • @tom about the decltype(auto): Hmm, looks like it's non-bogus specifically because your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case. But I still strongly recommend that you never use decltype(auto) in C++ until you can explain the behavior of this little snippet. (Which, in practice, means: never use it, ever. ;)) — P.S. I adjusted the cppreference page. ;)
            – Quuxplusone
            Apr 4 at 6:46











          • @Quuxplusone, or one can grab Effective Modern C++ :) I got a little bit confused about your comment on decltype(auto), but now I see that it applies only to your code.
            – Incomputable
            Apr 6 at 6:45










          • @Incomputable: I'm sure we're both being too vague. :) When I said "your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case", I was talking about Tom's code i.e. cppreference's code, and the first Wandbox link was an example demonstrating that concept in isolation. The word "this" in "this little snippet" was indeed intended to refer to the second Wandbox link itself.
            – Quuxplusone
            Apr 6 at 19:26












          up vote
          5
          down vote










          up vote
          5
          down vote









          Looks good to me! I mean, I'm not likely to convert to it because of its heavyweightness — you noted its use of std::apply, but it also pulls in all of <tuple> every time you use it, too. Also, it's arguably coincidental that your expressions a[I] and std::get<I>(t) work in this context, since what's actually happening in both cases is an implicit conversion from std::integral_constant<size_t, K> to size_t. In some contexts, the user might need to explicitly cast int(I) or whatever.



          You could remove the std::apply dependency and simplify the user's job at the same time by writing a helper function apply_to_sequence<N>(lambda), as in:



          // Convert array into a tuple
          template <typename T, std::size_t N>
          auto a2t(const std::array<T, N>& a)
          return apply_to_sequence<N>([&](auto... Is)
          return std::make_tuple(a[Is]...);
          );



          (Oh yeah, I think your use of decltype(auto) in this function was bogus and could result in dangling references. Certainly auto would be fine, so I recommend it.)



          // pretty-print a tuple
          template <class Ch, class Tr, class... Args>
          auto& operator<<(std::basic_ostream<Ch, Tr>& os,
          const std::tuple<Args...>& t)

          os << "(";
          apply_to_sequence<sizeof...(Args)>([&](auto... Is)
          ((os << (Is == 0 ? "" : ", ") << std::get<Is>(t)), ...);
          );
          return os << ")";



          Writing apply_to_sequence from scratch is left as an exercise for the reader, but the trivial C++17 implementation is just this:



          template<size_t N, class F>
          decltype(auto) apply_to_sequence(const F& fn)
          return std::apply(fn, integral_sequence<N>);



          Having hidden the implementation details apply and integral_sequence from the reader, we are now free — if we so desire — to replace them with things that are



          • faster

          • C++14-compatible


          • <tuple>-free

          One stylistic note: I prefer to name my parameter packs with plurals, so, singular auto I but plural auto... Is. That's the logic behind my renaming above.






          share|improve this answer













          Looks good to me! I mean, I'm not likely to convert to it because of its heavyweightness — you noted its use of std::apply, but it also pulls in all of <tuple> every time you use it, too. Also, it's arguably coincidental that your expressions a[I] and std::get<I>(t) work in this context, since what's actually happening in both cases is an implicit conversion from std::integral_constant<size_t, K> to size_t. In some contexts, the user might need to explicitly cast int(I) or whatever.



          You could remove the std::apply dependency and simplify the user's job at the same time by writing a helper function apply_to_sequence<N>(lambda), as in:



          // Convert array into a tuple
          template <typename T, std::size_t N>
          auto a2t(const std::array<T, N>& a)
          return apply_to_sequence<N>([&](auto... Is)
          return std::make_tuple(a[Is]...);
          );



          (Oh yeah, I think your use of decltype(auto) in this function was bogus and could result in dangling references. Certainly auto would be fine, so I recommend it.)



          // pretty-print a tuple
          template <class Ch, class Tr, class... Args>
          auto& operator<<(std::basic_ostream<Ch, Tr>& os,
          const std::tuple<Args...>& t)

          os << "(";
          apply_to_sequence<sizeof...(Args)>([&](auto... Is)
          ((os << (Is == 0 ? "" : ", ") << std::get<Is>(t)), ...);
          );
          return os << ")";



          Writing apply_to_sequence from scratch is left as an exercise for the reader, but the trivial C++17 implementation is just this:



          template<size_t N, class F>
          decltype(auto) apply_to_sequence(const F& fn)
          return std::apply(fn, integral_sequence<N>);



          Having hidden the implementation details apply and integral_sequence from the reader, we are now free — if we so desire — to replace them with things that are



          • faster

          • C++14-compatible


          • <tuple>-free

          One stylistic note: I prefer to name my parameter packs with plurals, so, singular auto I but plural auto... Is. That's the logic behind my renaming above.







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered Apr 3 at 22:40









          Quuxplusone

          9,82511451




          9,82511451











          • About the decltype(auto), I took the code straight from cppreference.com is the use there bogus too? Or is it specific to my code?
            – tom
            Apr 4 at 6:25










          • @tom about the decltype(auto): Hmm, looks like it's non-bogus specifically because your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case. But I still strongly recommend that you never use decltype(auto) in C++ until you can explain the behavior of this little snippet. (Which, in practice, means: never use it, ever. ;)) — P.S. I adjusted the cppreference page. ;)
            – Quuxplusone
            Apr 4 at 6:46











          • @Quuxplusone, or one can grab Effective Modern C++ :) I got a little bit confused about your comment on decltype(auto), but now I see that it applies only to your code.
            – Incomputable
            Apr 6 at 6:45










          • @Incomputable: I'm sure we're both being too vague. :) When I said "your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case", I was talking about Tom's code i.e. cppreference's code, and the first Wandbox link was an example demonstrating that concept in isolation. The word "this" in "this little snippet" was indeed intended to refer to the second Wandbox link itself.
            – Quuxplusone
            Apr 6 at 19:26
















          • About the decltype(auto), I took the code straight from cppreference.com is the use there bogus too? Or is it specific to my code?
            – tom
            Apr 4 at 6:25










          • @tom about the decltype(auto): Hmm, looks like it's non-bogus specifically because your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case. But I still strongly recommend that you never use decltype(auto) in C++ until you can explain the behavior of this little snippet. (Which, in practice, means: never use it, ever. ;)) — P.S. I adjusted the cppreference page. ;)
            – Quuxplusone
            Apr 4 at 6:46











          • @Quuxplusone, or one can grab Effective Modern C++ :) I got a little bit confused about your comment on decltype(auto), but now I see that it applies only to your code.
            – Incomputable
            Apr 6 at 6:45










          • @Incomputable: I'm sure we're both being too vague. :) When I said "your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case", I was talking about Tom's code i.e. cppreference's code, and the first Wandbox link was an example demonstrating that concept in isolation. The word "this" in "this little snippet" was indeed intended to refer to the second Wandbox link itself.
            – Quuxplusone
            Apr 6 at 19:26















          About the decltype(auto), I took the code straight from cppreference.com is the use there bogus too? Or is it specific to my code?
          – tom
          Apr 4 at 6:25




          About the decltype(auto), I took the code straight from cppreference.com is the use there bogus too? Or is it specific to my code?
          – tom
          Apr 4 at 6:25












          @tom about the decltype(auto): Hmm, looks like it's non-bogus specifically because your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case. But I still strongly recommend that you never use decltype(auto) in C++ until you can explain the behavior of this little snippet. (Which, in practice, means: never use it, ever. ;)) — P.S. I adjusted the cppreference page. ;)
          – Quuxplusone
          Apr 4 at 6:46





          @tom about the decltype(auto): Hmm, looks like it's non-bogus specifically because your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case. But I still strongly recommend that you never use decltype(auto) in C++ until you can explain the behavior of this little snippet. (Which, in practice, means: never use it, ever. ;)) — P.S. I adjusted the cppreference page. ;)
          – Quuxplusone
          Apr 4 at 6:46













          @Quuxplusone, or one can grab Effective Modern C++ :) I got a little bit confused about your comment on decltype(auto), but now I see that it applies only to your code.
          – Incomputable
          Apr 6 at 6:45




          @Quuxplusone, or one can grab Effective Modern C++ :) I got a little bit confused about your comment on decltype(auto), but now I see that it applies only to your code.
          – Incomputable
          Apr 6 at 6:45












          @Incomputable: I'm sure we're both being too vague. :) When I said "your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case", I was talking about Tom's code i.e. cppreference's code, and the first Wandbox link was an example demonstrating that concept in isolation. The word "this" in "this little snippet" was indeed intended to refer to the second Wandbox link itself.
          – Quuxplusone
          Apr 6 at 19:26




          @Incomputable: I'm sure we're both being too vague. :) When I said "your return statement returns a prvalue, so decltype(auto) is actually equivalent to auto in this case", I was talking about Tom's code i.e. cppreference's code, and the first Wandbox link was an example demonstrating that concept in isolation. The word "this" in "this little snippet" was indeed intended to refer to the second Wandbox link itself.
          – Quuxplusone
          Apr 6 at 19:26












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191203%2falternative-to-integer-sequence-trick%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Chat program with C++ and SFML

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          Will my employers contract hold up in court?