How to unroll a parameter pack from right to left Announcing the arrival of Valued Associate...

MLE of the unknown radius

Converted a Scalar function to a TVF function for parallel execution-Still running in Serial mode

How often does castling occur in grandmaster games?

Did Mueller's report provide an evidentiary basis for the claim of Russian govt election interference via social media?

How do I decide if I need to go for Normalization and not Standardization or vice-versa?

Crossing US/Canada Border for less than 24 hours

Sum letters are not two different

Put R under double integral

Take 2! Is this homebrew Lady of Pain warlock patron balanced?

Can a new player join a group only when a new campaign starts?

How would a mousetrap for use in space work?

If Windows 7 doesn't support WSL, then what does Linux subsystem option mean?

Co-worker has annoying ringtone

One-one communication

Is CEO the "profession" with the most psychopaths?

What is Adi Shankara referring to when he says "He has Vajra marks on his feet"?

How could we fake a moon landing now?

Why do early math courses focus on the cross sections of a cone and not on other 3D objects?

What does Turing mean by this statement?

Sentence order: Where to put もう

A term for a woman complaining about things/begging in a cute/childish way

What is "gratricide"?

When a candle burns, why does the top of wick glow if bottom of flame is hottest?

Is it possible for SQL statements to execute concurrently within a single session in SQL Server?



How to unroll a parameter pack from right to left



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!C++ template partial specialization: Why cant I match the last type in variadic-template?Partial template specialization with multiple template parameter packsWhy won't template parameter pack be deduced to multiple type arguments in function call?Clang vs GCC - Variadic template parameter pack followed by parameter with default value works in GCC 4.8 but not Clang 3.5Generating template specializations through template metaprogramming. Odd compiler behaviourHow to access first parameter in parameter pack?Can outer parameter pack be expanded with inner parameter pack to be deduced?Size of parameter pack in template specializationC++ template partial specialization: Why cant I match the last type in variadic-template?variadic vs non variadic function template overloading partial orderingFunction template overload resolution with two parameter packs





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







7















I am trying to do a parameter pack unrolling by dispatching to a class recursively. I'd like to do that from right to left since some of the operations do pre-pending.



template <typename... T>
class Foo;

template <typename T>
class Foo<T> {/* base case implementation*/};

template <typename T, typename R, typename... Rs>
class Foo<T, Rs..., R> {
private:
Foo<T, Rs...> foo_;
}


Unfortunately, the above gets me:



class template partial specialization contains template parameters that cannot be deduced;
this partial specialization will never be used


This seems odd to me, I would assume that even though the arguments has switched order, Foo<T, Rs..., R> should still match the template specialization.



I've looked at some similar questions:



Specifically, C++ template partial specialization: Why cant I match the last type in variadic-template?



However, the highest voted (non-accepted) answer doesn't make sense to me. Sure I understand that the template parameter pack declaration must be the last in the declaration, but I do that for the template specialization.



I'm not sure why the compiler cannot map Foo<T, Rs..., R> to the initial template declaration Foo<T...> and enforces the parameter pack declaration order there.



Other answers on that thread offer how to extract the last value, but that still doesn't allow you to do recursive parameter pack unrolling, which is sort of the whole point here. Is it just impossible to unroll a parameter pack from right to left?










share|improve this question




















  • 2





    Well you can revert the order of the argument then unroll left to right. You may look an implementation of revert here : bitbucket.org/MartinMorterol/glp/src/dev/include/… or here github.com/edouarda/brigand/blob/master/include/brigand/…

    – Martin Morterol
    1 hour ago













  • What compiler are you using? I get a more helpful error message with the latest gcc: wandbox.org/permlink/BF2aCVw62TrdkrGz

    – Paul Sanders
    1 hour ago











  • I can't fix it (edit must be 6 chars long...), but you have trivial error in your code example - 4 dots in first line of parameter pack declaration instead of 3

    – Michał Łoś
    1 hour ago


















7















I am trying to do a parameter pack unrolling by dispatching to a class recursively. I'd like to do that from right to left since some of the operations do pre-pending.



template <typename... T>
class Foo;

template <typename T>
class Foo<T> {/* base case implementation*/};

template <typename T, typename R, typename... Rs>
class Foo<T, Rs..., R> {
private:
Foo<T, Rs...> foo_;
}


Unfortunately, the above gets me:



class template partial specialization contains template parameters that cannot be deduced;
this partial specialization will never be used


This seems odd to me, I would assume that even though the arguments has switched order, Foo<T, Rs..., R> should still match the template specialization.



I've looked at some similar questions:



Specifically, C++ template partial specialization: Why cant I match the last type in variadic-template?



However, the highest voted (non-accepted) answer doesn't make sense to me. Sure I understand that the template parameter pack declaration must be the last in the declaration, but I do that for the template specialization.



I'm not sure why the compiler cannot map Foo<T, Rs..., R> to the initial template declaration Foo<T...> and enforces the parameter pack declaration order there.



Other answers on that thread offer how to extract the last value, but that still doesn't allow you to do recursive parameter pack unrolling, which is sort of the whole point here. Is it just impossible to unroll a parameter pack from right to left?










share|improve this question




















  • 2





    Well you can revert the order of the argument then unroll left to right. You may look an implementation of revert here : bitbucket.org/MartinMorterol/glp/src/dev/include/… or here github.com/edouarda/brigand/blob/master/include/brigand/…

    – Martin Morterol
    1 hour ago













  • What compiler are you using? I get a more helpful error message with the latest gcc: wandbox.org/permlink/BF2aCVw62TrdkrGz

    – Paul Sanders
    1 hour ago











  • I can't fix it (edit must be 6 chars long...), but you have trivial error in your code example - 4 dots in first line of parameter pack declaration instead of 3

    – Michał Łoś
    1 hour ago














7












7








7


3






I am trying to do a parameter pack unrolling by dispatching to a class recursively. I'd like to do that from right to left since some of the operations do pre-pending.



template <typename... T>
class Foo;

template <typename T>
class Foo<T> {/* base case implementation*/};

template <typename T, typename R, typename... Rs>
class Foo<T, Rs..., R> {
private:
Foo<T, Rs...> foo_;
}


Unfortunately, the above gets me:



class template partial specialization contains template parameters that cannot be deduced;
this partial specialization will never be used


This seems odd to me, I would assume that even though the arguments has switched order, Foo<T, Rs..., R> should still match the template specialization.



I've looked at some similar questions:



Specifically, C++ template partial specialization: Why cant I match the last type in variadic-template?



However, the highest voted (non-accepted) answer doesn't make sense to me. Sure I understand that the template parameter pack declaration must be the last in the declaration, but I do that for the template specialization.



I'm not sure why the compiler cannot map Foo<T, Rs..., R> to the initial template declaration Foo<T...> and enforces the parameter pack declaration order there.



Other answers on that thread offer how to extract the last value, but that still doesn't allow you to do recursive parameter pack unrolling, which is sort of the whole point here. Is it just impossible to unroll a parameter pack from right to left?










share|improve this question
















I am trying to do a parameter pack unrolling by dispatching to a class recursively. I'd like to do that from right to left since some of the operations do pre-pending.



template <typename... T>
class Foo;

template <typename T>
class Foo<T> {/* base case implementation*/};

template <typename T, typename R, typename... Rs>
class Foo<T, Rs..., R> {
private:
Foo<T, Rs...> foo_;
}


Unfortunately, the above gets me:



class template partial specialization contains template parameters that cannot be deduced;
this partial specialization will never be used


This seems odd to me, I would assume that even though the arguments has switched order, Foo<T, Rs..., R> should still match the template specialization.



I've looked at some similar questions:



Specifically, C++ template partial specialization: Why cant I match the last type in variadic-template?



However, the highest voted (non-accepted) answer doesn't make sense to me. Sure I understand that the template parameter pack declaration must be the last in the declaration, but I do that for the template specialization.



I'm not sure why the compiler cannot map Foo<T, Rs..., R> to the initial template declaration Foo<T...> and enforces the parameter pack declaration order there.



Other answers on that thread offer how to extract the last value, but that still doesn't allow you to do recursive parameter pack unrolling, which is sort of the whole point here. Is it just impossible to unroll a parameter pack from right to left?







c++ c++11






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 44 mins ago









Bob__

5,26331527




5,26331527










asked 1 hour ago









IdeaHatIdeaHat

5,7381340




5,7381340








  • 2





    Well you can revert the order of the argument then unroll left to right. You may look an implementation of revert here : bitbucket.org/MartinMorterol/glp/src/dev/include/… or here github.com/edouarda/brigand/blob/master/include/brigand/…

    – Martin Morterol
    1 hour ago













  • What compiler are you using? I get a more helpful error message with the latest gcc: wandbox.org/permlink/BF2aCVw62TrdkrGz

    – Paul Sanders
    1 hour ago











  • I can't fix it (edit must be 6 chars long...), but you have trivial error in your code example - 4 dots in first line of parameter pack declaration instead of 3

    – Michał Łoś
    1 hour ago














  • 2





    Well you can revert the order of the argument then unroll left to right. You may look an implementation of revert here : bitbucket.org/MartinMorterol/glp/src/dev/include/… or here github.com/edouarda/brigand/blob/master/include/brigand/…

    – Martin Morterol
    1 hour ago













  • What compiler are you using? I get a more helpful error message with the latest gcc: wandbox.org/permlink/BF2aCVw62TrdkrGz

    – Paul Sanders
    1 hour ago











  • I can't fix it (edit must be 6 chars long...), but you have trivial error in your code example - 4 dots in first line of parameter pack declaration instead of 3

    – Michał Łoś
    1 hour ago








2




2





Well you can revert the order of the argument then unroll left to right. You may look an implementation of revert here : bitbucket.org/MartinMorterol/glp/src/dev/include/… or here github.com/edouarda/brigand/blob/master/include/brigand/…

– Martin Morterol
1 hour ago







Well you can revert the order of the argument then unroll left to right. You may look an implementation of revert here : bitbucket.org/MartinMorterol/glp/src/dev/include/… or here github.com/edouarda/brigand/blob/master/include/brigand/…

– Martin Morterol
1 hour ago















What compiler are you using? I get a more helpful error message with the latest gcc: wandbox.org/permlink/BF2aCVw62TrdkrGz

– Paul Sanders
1 hour ago





What compiler are you using? I get a more helpful error message with the latest gcc: wandbox.org/permlink/BF2aCVw62TrdkrGz

– Paul Sanders
1 hour ago













I can't fix it (edit must be 6 chars long...), but you have trivial error in your code example - 4 dots in first line of parameter pack declaration instead of 3

– Michał Łoś
1 hour ago





I can't fix it (edit must be 6 chars long...), but you have trivial error in your code example - 4 dots in first line of parameter pack declaration instead of 3

– Michał Łoś
1 hour ago












3 Answers
3






active

oldest

votes


















4














Here is an utility to instatiate a template with a reverse order of template parameters:



#include <type_traits>
#include <tuple>

template <template <typename...> typename Template, typename ...Arg>
struct RevertHelper;

template <template <typename > typename Template, typename Arg>
struct RevertHelper<Template, Arg>
{
using Result = Template<Arg>;
};

template <template <typename... > typename Template, typename Head, typename ...Tail>
struct RevertHelper<Template, Head, Tail...>
{
private:
template <typename ...XArgs>
using BindToTail = Template<XArgs..., Head>;

public:

using Result = typename RevertHelper<BindToTail, Tail...>::Result;
};

static_assert(std::is_same_v<typename RevertHelper<std::tuple, int, double>::Result, std::tuple<double, int>>, "");


So if you need to instantiate Foo with template pack Args... being reversed you can use



typename RevertHelper<Foo, Args...>::Result


To do the parameter pack expansion the way you want, dispatch to the reversed implementation:



namespace internal {
template <typename... T>
class FooHelper;
template <typename T>
class FooHelper<T> {/* base implementation */}
template <typename L, typename R, typename... Rs>
class FooHelper<T> {
private:
Foo<T, Rs...> foo_helper_;
};
}
template <typename... T>
class Foo {
typename RevertHelper<internal::FooHelper, T...>::Result foo_helper_;
};





share|improve this answer


























  • So the idea is that the actually usable class inverses the order and then dispatches to a class that reverses the order, and do the unpacking in that helper class?

    – IdeaHat
    47 mins ago











  • "thanks i hate it" :-) . Added the code example. So much boilerplate to do something so simple.

    – IdeaHat
    36 mins ago











  • @IdeaHat, yes I meant something like that. You can even make "Foo" a template alias to a RevertHelper<internal::FooHelper, T...>

    – Dmitry Gordon
    34 mins ago



















2














Pattern matching in C++ template patterns is intentionally simplified for sake of simplicity of algorithm and understanding.



Take a look at hypothetical algorithm if this could be possible:




  1. Get some declaration: using X = Foo<int, char, bool, double>;

  2. Compiler checks specializations: first one is Foo - it's dropped.

  3. Compiler checks specializations: second one is your Foo<T, Rs..., R>



    1. T is int, we're fine.


    2. R's can be emtpy, let's try to skip it.


    3. R is char, but we're at the end of specialization parameters, let's get back to 2.


    4. R's is char


    5. R is bool, but we're at the end of specialization parameters, let's get back to 2.


    6. R's is char, bool


    7. R is double, we're fine, select this one




But this is only one scenario: another one would be to eat all parameters to the end and cut off one by one in order to try to match it. This can be problematic, because such template specialization would be inherently ambiguous with another possible specialization that doesn't seem to be an ambiguity here:



template<typename T, typename S>
class Foo<T, S> {};





share|improve this answer

































    0















    I'm not sure why the compiler cannot map Foo<T, Rs..., R> to the initial template declaration Foo<T...> and enforces the parameter pack declaration order there.




    Because partial ordering is already a really complex algorithm and adding extra complexity to that is fraught with peril. There was a proposal to make this work, which had this example:




    template <class A, class... B, class C> void foo(A a, B... b, C c);
    foo(1, 2, 3, 4); // b is deduced as [2, 3]



    Straightforward enough right? Now, what if C has a default argument? What does this do:



    template <class A, class... B, class C=int> void foo(A a, B... b, C c=5);
    foo(1, 2, 3, 4);


    There are two interpretations of this:





    • b is deduced as the pack {2, 3} and c is deduced as 4


    • b is deduced as the pack {2, 3, 4} and c is deduced as 5


    Which is intended? Or do we just disallow default arguments after a function parameter pack?





    Unfortunately, we have no nice pack indexing mechanism. In the meantime, just use Boost.Mp11:



    template <typename... T>
    class Foo;

    template <typename T>
    class Foo<T> {/* base case implementation*/};

    template <typename T, typename... Rs>
    class Foo<T, Rs...> {
    private:
    using R = mp_back<Foo>;
    mp_pop_back<Foo> foo_;
    };




    share
























      Your Answer






      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: "1"
      };
      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',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55762106%2fhow-to-unroll-a-parameter-pack-from-right-to-left%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      4














      Here is an utility to instatiate a template with a reverse order of template parameters:



      #include <type_traits>
      #include <tuple>

      template <template <typename...> typename Template, typename ...Arg>
      struct RevertHelper;

      template <template <typename > typename Template, typename Arg>
      struct RevertHelper<Template, Arg>
      {
      using Result = Template<Arg>;
      };

      template <template <typename... > typename Template, typename Head, typename ...Tail>
      struct RevertHelper<Template, Head, Tail...>
      {
      private:
      template <typename ...XArgs>
      using BindToTail = Template<XArgs..., Head>;

      public:

      using Result = typename RevertHelper<BindToTail, Tail...>::Result;
      };

      static_assert(std::is_same_v<typename RevertHelper<std::tuple, int, double>::Result, std::tuple<double, int>>, "");


      So if you need to instantiate Foo with template pack Args... being reversed you can use



      typename RevertHelper<Foo, Args...>::Result


      To do the parameter pack expansion the way you want, dispatch to the reversed implementation:



      namespace internal {
      template <typename... T>
      class FooHelper;
      template <typename T>
      class FooHelper<T> {/* base implementation */}
      template <typename L, typename R, typename... Rs>
      class FooHelper<T> {
      private:
      Foo<T, Rs...> foo_helper_;
      };
      }
      template <typename... T>
      class Foo {
      typename RevertHelper<internal::FooHelper, T...>::Result foo_helper_;
      };





      share|improve this answer


























      • So the idea is that the actually usable class inverses the order and then dispatches to a class that reverses the order, and do the unpacking in that helper class?

        – IdeaHat
        47 mins ago











      • "thanks i hate it" :-) . Added the code example. So much boilerplate to do something so simple.

        – IdeaHat
        36 mins ago











      • @IdeaHat, yes I meant something like that. You can even make "Foo" a template alias to a RevertHelper<internal::FooHelper, T...>

        – Dmitry Gordon
        34 mins ago
















      4














      Here is an utility to instatiate a template with a reverse order of template parameters:



      #include <type_traits>
      #include <tuple>

      template <template <typename...> typename Template, typename ...Arg>
      struct RevertHelper;

      template <template <typename > typename Template, typename Arg>
      struct RevertHelper<Template, Arg>
      {
      using Result = Template<Arg>;
      };

      template <template <typename... > typename Template, typename Head, typename ...Tail>
      struct RevertHelper<Template, Head, Tail...>
      {
      private:
      template <typename ...XArgs>
      using BindToTail = Template<XArgs..., Head>;

      public:

      using Result = typename RevertHelper<BindToTail, Tail...>::Result;
      };

      static_assert(std::is_same_v<typename RevertHelper<std::tuple, int, double>::Result, std::tuple<double, int>>, "");


      So if you need to instantiate Foo with template pack Args... being reversed you can use



      typename RevertHelper<Foo, Args...>::Result


      To do the parameter pack expansion the way you want, dispatch to the reversed implementation:



      namespace internal {
      template <typename... T>
      class FooHelper;
      template <typename T>
      class FooHelper<T> {/* base implementation */}
      template <typename L, typename R, typename... Rs>
      class FooHelper<T> {
      private:
      Foo<T, Rs...> foo_helper_;
      };
      }
      template <typename... T>
      class Foo {
      typename RevertHelper<internal::FooHelper, T...>::Result foo_helper_;
      };





      share|improve this answer


























      • So the idea is that the actually usable class inverses the order and then dispatches to a class that reverses the order, and do the unpacking in that helper class?

        – IdeaHat
        47 mins ago











      • "thanks i hate it" :-) . Added the code example. So much boilerplate to do something so simple.

        – IdeaHat
        36 mins ago











      • @IdeaHat, yes I meant something like that. You can even make "Foo" a template alias to a RevertHelper<internal::FooHelper, T...>

        – Dmitry Gordon
        34 mins ago














      4












      4








      4







      Here is an utility to instatiate a template with a reverse order of template parameters:



      #include <type_traits>
      #include <tuple>

      template <template <typename...> typename Template, typename ...Arg>
      struct RevertHelper;

      template <template <typename > typename Template, typename Arg>
      struct RevertHelper<Template, Arg>
      {
      using Result = Template<Arg>;
      };

      template <template <typename... > typename Template, typename Head, typename ...Tail>
      struct RevertHelper<Template, Head, Tail...>
      {
      private:
      template <typename ...XArgs>
      using BindToTail = Template<XArgs..., Head>;

      public:

      using Result = typename RevertHelper<BindToTail, Tail...>::Result;
      };

      static_assert(std::is_same_v<typename RevertHelper<std::tuple, int, double>::Result, std::tuple<double, int>>, "");


      So if you need to instantiate Foo with template pack Args... being reversed you can use



      typename RevertHelper<Foo, Args...>::Result


      To do the parameter pack expansion the way you want, dispatch to the reversed implementation:



      namespace internal {
      template <typename... T>
      class FooHelper;
      template <typename T>
      class FooHelper<T> {/* base implementation */}
      template <typename L, typename R, typename... Rs>
      class FooHelper<T> {
      private:
      Foo<T, Rs...> foo_helper_;
      };
      }
      template <typename... T>
      class Foo {
      typename RevertHelper<internal::FooHelper, T...>::Result foo_helper_;
      };





      share|improve this answer















      Here is an utility to instatiate a template with a reverse order of template parameters:



      #include <type_traits>
      #include <tuple>

      template <template <typename...> typename Template, typename ...Arg>
      struct RevertHelper;

      template <template <typename > typename Template, typename Arg>
      struct RevertHelper<Template, Arg>
      {
      using Result = Template<Arg>;
      };

      template <template <typename... > typename Template, typename Head, typename ...Tail>
      struct RevertHelper<Template, Head, Tail...>
      {
      private:
      template <typename ...XArgs>
      using BindToTail = Template<XArgs..., Head>;

      public:

      using Result = typename RevertHelper<BindToTail, Tail...>::Result;
      };

      static_assert(std::is_same_v<typename RevertHelper<std::tuple, int, double>::Result, std::tuple<double, int>>, "");


      So if you need to instantiate Foo with template pack Args... being reversed you can use



      typename RevertHelper<Foo, Args...>::Result


      To do the parameter pack expansion the way you want, dispatch to the reversed implementation:



      namespace internal {
      template <typename... T>
      class FooHelper;
      template <typename T>
      class FooHelper<T> {/* base implementation */}
      template <typename L, typename R, typename... Rs>
      class FooHelper<T> {
      private:
      Foo<T, Rs...> foo_helper_;
      };
      }
      template <typename... T>
      class Foo {
      typename RevertHelper<internal::FooHelper, T...>::Result foo_helper_;
      };






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 38 mins ago









      IdeaHat

      5,7381340




      5,7381340










      answered 1 hour ago









      Dmitry GordonDmitry Gordon

      1,089614




      1,089614













      • So the idea is that the actually usable class inverses the order and then dispatches to a class that reverses the order, and do the unpacking in that helper class?

        – IdeaHat
        47 mins ago











      • "thanks i hate it" :-) . Added the code example. So much boilerplate to do something so simple.

        – IdeaHat
        36 mins ago











      • @IdeaHat, yes I meant something like that. You can even make "Foo" a template alias to a RevertHelper<internal::FooHelper, T...>

        – Dmitry Gordon
        34 mins ago



















      • So the idea is that the actually usable class inverses the order and then dispatches to a class that reverses the order, and do the unpacking in that helper class?

        – IdeaHat
        47 mins ago











      • "thanks i hate it" :-) . Added the code example. So much boilerplate to do something so simple.

        – IdeaHat
        36 mins ago











      • @IdeaHat, yes I meant something like that. You can even make "Foo" a template alias to a RevertHelper<internal::FooHelper, T...>

        – Dmitry Gordon
        34 mins ago

















      So the idea is that the actually usable class inverses the order and then dispatches to a class that reverses the order, and do the unpacking in that helper class?

      – IdeaHat
      47 mins ago





      So the idea is that the actually usable class inverses the order and then dispatches to a class that reverses the order, and do the unpacking in that helper class?

      – IdeaHat
      47 mins ago













      "thanks i hate it" :-) . Added the code example. So much boilerplate to do something so simple.

      – IdeaHat
      36 mins ago





      "thanks i hate it" :-) . Added the code example. So much boilerplate to do something so simple.

      – IdeaHat
      36 mins ago













      @IdeaHat, yes I meant something like that. You can even make "Foo" a template alias to a RevertHelper<internal::FooHelper, T...>

      – Dmitry Gordon
      34 mins ago





      @IdeaHat, yes I meant something like that. You can even make "Foo" a template alias to a RevertHelper<internal::FooHelper, T...>

      – Dmitry Gordon
      34 mins ago













      2














      Pattern matching in C++ template patterns is intentionally simplified for sake of simplicity of algorithm and understanding.



      Take a look at hypothetical algorithm if this could be possible:




      1. Get some declaration: using X = Foo<int, char, bool, double>;

      2. Compiler checks specializations: first one is Foo - it's dropped.

      3. Compiler checks specializations: second one is your Foo<T, Rs..., R>



        1. T is int, we're fine.


        2. R's can be emtpy, let's try to skip it.


        3. R is char, but we're at the end of specialization parameters, let's get back to 2.


        4. R's is char


        5. R is bool, but we're at the end of specialization parameters, let's get back to 2.


        6. R's is char, bool


        7. R is double, we're fine, select this one




      But this is only one scenario: another one would be to eat all parameters to the end and cut off one by one in order to try to match it. This can be problematic, because such template specialization would be inherently ambiguous with another possible specialization that doesn't seem to be an ambiguity here:



      template<typename T, typename S>
      class Foo<T, S> {};





      share|improve this answer






























        2














        Pattern matching in C++ template patterns is intentionally simplified for sake of simplicity of algorithm and understanding.



        Take a look at hypothetical algorithm if this could be possible:




        1. Get some declaration: using X = Foo<int, char, bool, double>;

        2. Compiler checks specializations: first one is Foo - it's dropped.

        3. Compiler checks specializations: second one is your Foo<T, Rs..., R>



          1. T is int, we're fine.


          2. R's can be emtpy, let's try to skip it.


          3. R is char, but we're at the end of specialization parameters, let's get back to 2.


          4. R's is char


          5. R is bool, but we're at the end of specialization parameters, let's get back to 2.


          6. R's is char, bool


          7. R is double, we're fine, select this one




        But this is only one scenario: another one would be to eat all parameters to the end and cut off one by one in order to try to match it. This can be problematic, because such template specialization would be inherently ambiguous with another possible specialization that doesn't seem to be an ambiguity here:



        template<typename T, typename S>
        class Foo<T, S> {};





        share|improve this answer




























          2












          2








          2







          Pattern matching in C++ template patterns is intentionally simplified for sake of simplicity of algorithm and understanding.



          Take a look at hypothetical algorithm if this could be possible:




          1. Get some declaration: using X = Foo<int, char, bool, double>;

          2. Compiler checks specializations: first one is Foo - it's dropped.

          3. Compiler checks specializations: second one is your Foo<T, Rs..., R>



            1. T is int, we're fine.


            2. R's can be emtpy, let's try to skip it.


            3. R is char, but we're at the end of specialization parameters, let's get back to 2.


            4. R's is char


            5. R is bool, but we're at the end of specialization parameters, let's get back to 2.


            6. R's is char, bool


            7. R is double, we're fine, select this one




          But this is only one scenario: another one would be to eat all parameters to the end and cut off one by one in order to try to match it. This can be problematic, because such template specialization would be inherently ambiguous with another possible specialization that doesn't seem to be an ambiguity here:



          template<typename T, typename S>
          class Foo<T, S> {};





          share|improve this answer















          Pattern matching in C++ template patterns is intentionally simplified for sake of simplicity of algorithm and understanding.



          Take a look at hypothetical algorithm if this could be possible:




          1. Get some declaration: using X = Foo<int, char, bool, double>;

          2. Compiler checks specializations: first one is Foo - it's dropped.

          3. Compiler checks specializations: second one is your Foo<T, Rs..., R>



            1. T is int, we're fine.


            2. R's can be emtpy, let's try to skip it.


            3. R is char, but we're at the end of specialization parameters, let's get back to 2.


            4. R's is char


            5. R is bool, but we're at the end of specialization parameters, let's get back to 2.


            6. R's is char, bool


            7. R is double, we're fine, select this one




          But this is only one scenario: another one would be to eat all parameters to the end and cut off one by one in order to try to match it. This can be problematic, because such template specialization would be inherently ambiguous with another possible specialization that doesn't seem to be an ambiguity here:



          template<typename T, typename S>
          class Foo<T, S> {};






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 48 mins ago









          Stack Danny

          2,173932




          2,173932










          answered 1 hour ago









          Michał ŁośMichał Łoś

          508312




          508312























              0















              I'm not sure why the compiler cannot map Foo<T, Rs..., R> to the initial template declaration Foo<T...> and enforces the parameter pack declaration order there.




              Because partial ordering is already a really complex algorithm and adding extra complexity to that is fraught with peril. There was a proposal to make this work, which had this example:




              template <class A, class... B, class C> void foo(A a, B... b, C c);
              foo(1, 2, 3, 4); // b is deduced as [2, 3]



              Straightforward enough right? Now, what if C has a default argument? What does this do:



              template <class A, class... B, class C=int> void foo(A a, B... b, C c=5);
              foo(1, 2, 3, 4);


              There are two interpretations of this:





              • b is deduced as the pack {2, 3} and c is deduced as 4


              • b is deduced as the pack {2, 3, 4} and c is deduced as 5


              Which is intended? Or do we just disallow default arguments after a function parameter pack?





              Unfortunately, we have no nice pack indexing mechanism. In the meantime, just use Boost.Mp11:



              template <typename... T>
              class Foo;

              template <typename T>
              class Foo<T> {/* base case implementation*/};

              template <typename T, typename... Rs>
              class Foo<T, Rs...> {
              private:
              using R = mp_back<Foo>;
              mp_pop_back<Foo> foo_;
              };




              share




























                0















                I'm not sure why the compiler cannot map Foo<T, Rs..., R> to the initial template declaration Foo<T...> and enforces the parameter pack declaration order there.




                Because partial ordering is already a really complex algorithm and adding extra complexity to that is fraught with peril. There was a proposal to make this work, which had this example:




                template <class A, class... B, class C> void foo(A a, B... b, C c);
                foo(1, 2, 3, 4); // b is deduced as [2, 3]



                Straightforward enough right? Now, what if C has a default argument? What does this do:



                template <class A, class... B, class C=int> void foo(A a, B... b, C c=5);
                foo(1, 2, 3, 4);


                There are two interpretations of this:





                • b is deduced as the pack {2, 3} and c is deduced as 4


                • b is deduced as the pack {2, 3, 4} and c is deduced as 5


                Which is intended? Or do we just disallow default arguments after a function parameter pack?





                Unfortunately, we have no nice pack indexing mechanism. In the meantime, just use Boost.Mp11:



                template <typename... T>
                class Foo;

                template <typename T>
                class Foo<T> {/* base case implementation*/};

                template <typename T, typename... Rs>
                class Foo<T, Rs...> {
                private:
                using R = mp_back<Foo>;
                mp_pop_back<Foo> foo_;
                };




                share


























                  0












                  0








                  0








                  I'm not sure why the compiler cannot map Foo<T, Rs..., R> to the initial template declaration Foo<T...> and enforces the parameter pack declaration order there.




                  Because partial ordering is already a really complex algorithm and adding extra complexity to that is fraught with peril. There was a proposal to make this work, which had this example:




                  template <class A, class... B, class C> void foo(A a, B... b, C c);
                  foo(1, 2, 3, 4); // b is deduced as [2, 3]



                  Straightforward enough right? Now, what if C has a default argument? What does this do:



                  template <class A, class... B, class C=int> void foo(A a, B... b, C c=5);
                  foo(1, 2, 3, 4);


                  There are two interpretations of this:





                  • b is deduced as the pack {2, 3} and c is deduced as 4


                  • b is deduced as the pack {2, 3, 4} and c is deduced as 5


                  Which is intended? Or do we just disallow default arguments after a function parameter pack?





                  Unfortunately, we have no nice pack indexing mechanism. In the meantime, just use Boost.Mp11:



                  template <typename... T>
                  class Foo;

                  template <typename T>
                  class Foo<T> {/* base case implementation*/};

                  template <typename T, typename... Rs>
                  class Foo<T, Rs...> {
                  private:
                  using R = mp_back<Foo>;
                  mp_pop_back<Foo> foo_;
                  };




                  share














                  I'm not sure why the compiler cannot map Foo<T, Rs..., R> to the initial template declaration Foo<T...> and enforces the parameter pack declaration order there.




                  Because partial ordering is already a really complex algorithm and adding extra complexity to that is fraught with peril. There was a proposal to make this work, which had this example:




                  template <class A, class... B, class C> void foo(A a, B... b, C c);
                  foo(1, 2, 3, 4); // b is deduced as [2, 3]



                  Straightforward enough right? Now, what if C has a default argument? What does this do:



                  template <class A, class... B, class C=int> void foo(A a, B... b, C c=5);
                  foo(1, 2, 3, 4);


                  There are two interpretations of this:





                  • b is deduced as the pack {2, 3} and c is deduced as 4


                  • b is deduced as the pack {2, 3, 4} and c is deduced as 5


                  Which is intended? Or do we just disallow default arguments after a function parameter pack?





                  Unfortunately, we have no nice pack indexing mechanism. In the meantime, just use Boost.Mp11:



                  template <typename... T>
                  class Foo;

                  template <typename T>
                  class Foo<T> {/* base case implementation*/};

                  template <typename T, typename... Rs>
                  class Foo<T, Rs...> {
                  private:
                  using R = mp_back<Foo>;
                  mp_pop_back<Foo> foo_;
                  };





                  share











                  share


                  share










                  answered 9 mins ago









                  BarryBarry

                  187k21331612




                  187k21331612






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55762106%2fhow-to-unroll-a-parameter-pack-from-right-to-left%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      ORA-01691 (unable to extend lob segment) even though my tablespace has AUTOEXTEND onORA-01692: unable to...

                      Always On Availability groups resolving state after failover - Remote harden of transaction...

                      Circunscripción electoral de Guipúzcoa Referencias Menú de navegaciónLas claves del sistema electoral en...