The variadic template constructor of my class cannot modify my class members, why is that so? ...

Writing Thesis: Copying from published papers

Are my PIs rude or am I just being too sensitive?

How can you insert a "times/divide" symbol similar to the "plus/minus" (±) one?

Passing functions in C++

How do I keep my slimes from escaping their pens?

Why use gamma over alpha radiation?

Unexpected result with right shift after bitwise negation

How should I respond to a player wanting to catch a sword between their hands?

Can I throw a longsword at someone?

Is dark matter really a meaningful hypothesis?

Area of a 2D convex hull

How is simplicity better than precision and clarity in prose?

Is it possible to ask for a hotel room without minibar/extra services?

What computer would be fastest for Mathematica Home Edition?

How to politely respond to generic emails requesting a PhD/job in my lab? Without wasting too much time

Blender game recording at the wrong time

AWS IAM: Restrict Console Access to only One Instance

When is phishing education going too far?

3 doors, three guards, one stone

How does modal jazz use chord progressions?

What can I do if my MacBook isn’t charging but already ran out?

Sorting inherited template fields

Cauchy Sequence Characterized only By Directly Neighbouring Sequence Members

What do I do if technical issues prevent me from filing my return on time?



The variadic template constructor of my class cannot modify my class members, why is that so?



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
The Ask Question Wizard is Live!
Data science time! April 2019 and salary with experienceWhy can templates only be implemented in the header file?Where and why do I have to put the “template” and “typename” keywords?Variadic Template TemplateClass Headers and using constructors in my class .cpp file: “error: class 'Test' does not have any field named 'counter'”C++ confused between cast operator and variadic constructorIs it possible to create a completely arbitrary private member tuple in a C++11 variadic class constructor?How to solve this with variadic templatesVariadic Typenames in Template Functionsmetaprogramming with variadic templates in C++Template variadic argument referenced from another argument





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







16















I've been working on a task we got by our professor, where I have to work around a variadic template class.
The problem is, I cannot modify the class members within the recursive constructor. I cannot figure out why this is the case, as soon as it goes into the next constructor call, it will discard my changes on the variable.



What I have tried:




  • using pointer int* count instead of int count


  • using a setter to set the counter



I have already googled around for hours, but cannot find a solving answer.



Header file "test.h":



#include <cstdarg>
#include <iostream>

class Counter {
private:
int count = 0;
int tmp;

public:
template <typename... Rest> Counter (int t, Rest... rest) {
count++;
std::cout << "start recursive number " << count << "...n";
Counter(rest ...);
tmp = t;
std::cout << "end recursive number " << count << "...n";
}
Counter (int t) {
count++;
tmp = t;
std::cout << "reached end of recursive -> " << count << "n";
}
};


main.cpp:



#include "test.h"
int main () {
Counter a {0, 1, 2, 3, 4};
}


The output I got:



start recursive number 1...
start recursive number 1...
start recursive number 1...
start recursive number 1...
reached end of recursive -> 1
end recursive number 1...
end recursive number 1...
end recursive number 1...
end recursive number 1...









share|improve this question









New contributor




PrettyCoffee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





















  • Perhaps the intention here is for count to be static, I'm not certain if that's considered modifying the variable? Either way I imagine your intent is to print tmp.

    – Jonathan Mee
    yesterday


















16















I've been working on a task we got by our professor, where I have to work around a variadic template class.
The problem is, I cannot modify the class members within the recursive constructor. I cannot figure out why this is the case, as soon as it goes into the next constructor call, it will discard my changes on the variable.



What I have tried:




  • using pointer int* count instead of int count


  • using a setter to set the counter



I have already googled around for hours, but cannot find a solving answer.



Header file "test.h":



#include <cstdarg>
#include <iostream>

class Counter {
private:
int count = 0;
int tmp;

public:
template <typename... Rest> Counter (int t, Rest... rest) {
count++;
std::cout << "start recursive number " << count << "...n";
Counter(rest ...);
tmp = t;
std::cout << "end recursive number " << count << "...n";
}
Counter (int t) {
count++;
tmp = t;
std::cout << "reached end of recursive -> " << count << "n";
}
};


main.cpp:



#include "test.h"
int main () {
Counter a {0, 1, 2, 3, 4};
}


The output I got:



start recursive number 1...
start recursive number 1...
start recursive number 1...
start recursive number 1...
reached end of recursive -> 1
end recursive number 1...
end recursive number 1...
end recursive number 1...
end recursive number 1...









share|improve this question









New contributor




PrettyCoffee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





















  • Perhaps the intention here is for count to be static, I'm not certain if that's considered modifying the variable? Either way I imagine your intent is to print tmp.

    – Jonathan Mee
    yesterday














16












16








16








I've been working on a task we got by our professor, where I have to work around a variadic template class.
The problem is, I cannot modify the class members within the recursive constructor. I cannot figure out why this is the case, as soon as it goes into the next constructor call, it will discard my changes on the variable.



What I have tried:




  • using pointer int* count instead of int count


  • using a setter to set the counter



I have already googled around for hours, but cannot find a solving answer.



Header file "test.h":



#include <cstdarg>
#include <iostream>

class Counter {
private:
int count = 0;
int tmp;

public:
template <typename... Rest> Counter (int t, Rest... rest) {
count++;
std::cout << "start recursive number " << count << "...n";
Counter(rest ...);
tmp = t;
std::cout << "end recursive number " << count << "...n";
}
Counter (int t) {
count++;
tmp = t;
std::cout << "reached end of recursive -> " << count << "n";
}
};


main.cpp:



#include "test.h"
int main () {
Counter a {0, 1, 2, 3, 4};
}


The output I got:



start recursive number 1...
start recursive number 1...
start recursive number 1...
start recursive number 1...
reached end of recursive -> 1
end recursive number 1...
end recursive number 1...
end recursive number 1...
end recursive number 1...









share|improve this question









New contributor




PrettyCoffee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












I've been working on a task we got by our professor, where I have to work around a variadic template class.
The problem is, I cannot modify the class members within the recursive constructor. I cannot figure out why this is the case, as soon as it goes into the next constructor call, it will discard my changes on the variable.



What I have tried:




  • using pointer int* count instead of int count


  • using a setter to set the counter



I have already googled around for hours, but cannot find a solving answer.



Header file "test.h":



#include <cstdarg>
#include <iostream>

class Counter {
private:
int count = 0;
int tmp;

public:
template <typename... Rest> Counter (int t, Rest... rest) {
count++;
std::cout << "start recursive number " << count << "...n";
Counter(rest ...);
tmp = t;
std::cout << "end recursive number " << count << "...n";
}
Counter (int t) {
count++;
tmp = t;
std::cout << "reached end of recursive -> " << count << "n";
}
};


main.cpp:



#include "test.h"
int main () {
Counter a {0, 1, 2, 3, 4};
}


The output I got:



start recursive number 1...
start recursive number 1...
start recursive number 1...
start recursive number 1...
reached end of recursive -> 1
end recursive number 1...
end recursive number 1...
end recursive number 1...
end recursive number 1...






c++ c++11 recursion variadic-templates






share|improve this question









New contributor




PrettyCoffee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




PrettyCoffee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited yesterday









TrebledJ

3,90421431




3,90421431






New contributor




PrettyCoffee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked yesterday









PrettyCoffeePrettyCoffee

814




814




New contributor




PrettyCoffee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





PrettyCoffee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






PrettyCoffee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.













  • Perhaps the intention here is for count to be static, I'm not certain if that's considered modifying the variable? Either way I imagine your intent is to print tmp.

    – Jonathan Mee
    yesterday



















  • Perhaps the intention here is for count to be static, I'm not certain if that's considered modifying the variable? Either way I imagine your intent is to print tmp.

    – Jonathan Mee
    yesterday

















Perhaps the intention here is for count to be static, I'm not certain if that's considered modifying the variable? Either way I imagine your intent is to print tmp.

– Jonathan Mee
yesterday





Perhaps the intention here is for count to be static, I'm not certain if that's considered modifying the variable? Either way I imagine your intent is to print tmp.

– Jonathan Mee
yesterday












2 Answers
2






active

oldest

votes


















22














Counter(rest ...); creates an unnamed temporary object, it does not recursively invoke constructor for this object. Each object is spawned with its own count therefore you get stream of 1 1 1 1



If you want to delegate object initialization to different constructor then it should be present in member initialization list. This does not seem like a good idea though:



template <typename... Rest> Counter (int t, Rest... rest)
: Counter{rest...}
{
count++;
std::cout << "start recursive number " << count << "...n";
tmp = t;
std::cout << "end recursive number " << count << "...n";
}





share|improve this answer

































    11














    As explained by VTT, calling Counter() inside the body of the constructor create a new Counter() object.



    You can call, recursively, the contructors but you have to do this in the initialization list: look for "delegating contructors" for more informations.



    I also would advise you against initialization (and modifications) of member object inside the body of contructors.



    If your target is initialize count with the number of the arguments and tmp with the value of the last argument, I propose the following ("tag dispatching" based) solution



    class Counter
    {
    private:
    struct tag
    { };

    int count = 0;
    int tmp;

    Counter (tag tg, std::size_t c0, int t) : count(c0), tmp{t}
    { std::cout << "end: " << tmp << ", " <<count << "n"; }

    template <typename... Rest>
    Counter (tag t0, std::size_t c0, int t, Rest... rest)
    : Counter{t0, c0, rest...}
    { std::cout << "recursion: " << tmp << ", " << count << "n"; }

    public:
    template <typename... Rest>
    Counter (Rest... rest) : Counter{tag{}, sizeof...(Rest), rest...}
    { std::cout << "start: " << tmp << ", " << count << "n"; }
    };


    You can also avoid tag-dispatching and constructor recursion delegating the recursion about rest... to a method (maybe static and also constexpr, if you want) used to initialize tmp



    class Counter
    {
    private:
    int count = 0;
    int tmp;

    static int getLastInt (int i)
    { return i; }

    template <typename ... Rest>
    static int getLastInt (int, Rest ... rs)
    { return getLastInt(rs...); }

    public:
    template <typename... Rest>
    Counter (Rest... rest)
    : count(sizeof...(Rest)), tmp{getLastInt(rest...)}
    { std::cout << tmp << ", " << count << "n"; }
    };


    Off Topic: to be precise, your Counter class isn't "a variadic template class".



    It's an ordinary (not template) class with one (two, in my first solution) variadic template constructor(s).



    -- EDIT --



    The OP asks




    What if I need to get the count as a static const variable and an int array with the length of the counter within compile time and as class members? (Array will be filled with all constructor arguments) Is this within the C++ possibilitys?




    A static const (maybe also constexpr) make sense only if the counter is a common value between all the instances of the class.



    At the moment doesn't make sense because your Counter accept initialization lists of different length.



    But suppose that number of the argument of the constructor is a template parameter (say N)... in that case count is simply N and can be static constexpr. You can define a std::array<int, N> for the values (also a int[N] but I suggest to avoid to use C-style arrays, when possible, and use std::array instead) and, making the constructor constexpr, you can impose the compile time initialization.



    The following is a full compiling C++14 example (uses std::make_index_sequence and std::index_sequence that, unfortunately, are available only starting from C++14).



    Observe that I've defined the f8 variable in main() as constexpr: only this way you can impose (pretending there isn't the as-is rule) that f8 is initialized compile-time



    #include <array>
    #include <iostream>
    #include <type_traits>

    template <typename T, std::size_t>
    using getType = T;

    template <std::size_t N, typename = std::make_index_sequence<N>>
    struct foo;

    template <std::size_t N, std::size_t ... Is>
    struct foo<N, std::index_sequence<Is...>>
    {
    static_assert( sizeof...(Is), "!" );

    static constexpr auto count = N;

    const std::array<int, N> arr;

    constexpr foo (getType<int, Is> ... is) : arr {{ is ... }}
    { }
    };

    int main ()
    {
    constexpr foo<8u> f8 { 2, 3, 5, 7, 11, 13, 17, 19 };

    for ( auto const & i : f8.arr )
    std::cout << i << ' ';

    std::cout << std::endl;
    }


    If you can use a C++17 enabled compiler, you can also use a deduction guide for foo



    template <typename ... Args>
    foo(Args...) -> foo<sizeof...(Args)>;


    so there is no needs to explicate the template argument defining f8



    // .......VVV  no more "<8u>"
    constexpr foo f3{ 2, 3, 5, 7, 11, 13, 17, 19 };


    because it's deduced from the number of the argument of the constructor.






    share|improve this answer


























    • Thank u very much for the hint, that helped a lot! What if I need to get the count as a static const variable and an int array with the length of the counter within compile time and as class members? (Array will be filled with all constructor arguments) Is this within the C++ possibilitys?

      – PrettyCoffee
      yesterday











    • @PrettyCoffee - Let me think... Take in count that a static variable is a variable common to all instances of the class, so a static count variable (constant, moreover) make sense only if the count value is common to all instances of Counter. At the moment do not make sense because you can call the constructor of different instances with different number of arguments. It's different if the number of the template argument is a template parameter of the class. Give me some minutes and I prepare an example of what I mean.

      – max66
      yesterday











    • @PrettyCoffee - answer improved; hope this helps.

      – max66
      yesterday












    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
    });


    }
    });






    PrettyCoffee is a new contributor. Be nice, and check out our Code of Conduct.










    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55665792%2fthe-variadic-template-constructor-of-my-class-cannot-modify-my-class-members-wh%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    22














    Counter(rest ...); creates an unnamed temporary object, it does not recursively invoke constructor for this object. Each object is spawned with its own count therefore you get stream of 1 1 1 1



    If you want to delegate object initialization to different constructor then it should be present in member initialization list. This does not seem like a good idea though:



    template <typename... Rest> Counter (int t, Rest... rest)
    : Counter{rest...}
    {
    count++;
    std::cout << "start recursive number " << count << "...n";
    tmp = t;
    std::cout << "end recursive number " << count << "...n";
    }





    share|improve this answer






























      22














      Counter(rest ...); creates an unnamed temporary object, it does not recursively invoke constructor for this object. Each object is spawned with its own count therefore you get stream of 1 1 1 1



      If you want to delegate object initialization to different constructor then it should be present in member initialization list. This does not seem like a good idea though:



      template <typename... Rest> Counter (int t, Rest... rest)
      : Counter{rest...}
      {
      count++;
      std::cout << "start recursive number " << count << "...n";
      tmp = t;
      std::cout << "end recursive number " << count << "...n";
      }





      share|improve this answer




























        22












        22








        22







        Counter(rest ...); creates an unnamed temporary object, it does not recursively invoke constructor for this object. Each object is spawned with its own count therefore you get stream of 1 1 1 1



        If you want to delegate object initialization to different constructor then it should be present in member initialization list. This does not seem like a good idea though:



        template <typename... Rest> Counter (int t, Rest... rest)
        : Counter{rest...}
        {
        count++;
        std::cout << "start recursive number " << count << "...n";
        tmp = t;
        std::cout << "end recursive number " << count << "...n";
        }





        share|improve this answer















        Counter(rest ...); creates an unnamed temporary object, it does not recursively invoke constructor for this object. Each object is spawned with its own count therefore you get stream of 1 1 1 1



        If you want to delegate object initialization to different constructor then it should be present in member initialization list. This does not seem like a good idea though:



        template <typename... Rest> Counter (int t, Rest... rest)
        : Counter{rest...}
        {
        count++;
        std::cout << "start recursive number " << count << "...n";
        tmp = t;
        std::cout << "end recursive number " << count << "...n";
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited yesterday

























        answered yesterday









        VTTVTT

        26.3k42550




        26.3k42550

























            11














            As explained by VTT, calling Counter() inside the body of the constructor create a new Counter() object.



            You can call, recursively, the contructors but you have to do this in the initialization list: look for "delegating contructors" for more informations.



            I also would advise you against initialization (and modifications) of member object inside the body of contructors.



            If your target is initialize count with the number of the arguments and tmp with the value of the last argument, I propose the following ("tag dispatching" based) solution



            class Counter
            {
            private:
            struct tag
            { };

            int count = 0;
            int tmp;

            Counter (tag tg, std::size_t c0, int t) : count(c0), tmp{t}
            { std::cout << "end: " << tmp << ", " <<count << "n"; }

            template <typename... Rest>
            Counter (tag t0, std::size_t c0, int t, Rest... rest)
            : Counter{t0, c0, rest...}
            { std::cout << "recursion: " << tmp << ", " << count << "n"; }

            public:
            template <typename... Rest>
            Counter (Rest... rest) : Counter{tag{}, sizeof...(Rest), rest...}
            { std::cout << "start: " << tmp << ", " << count << "n"; }
            };


            You can also avoid tag-dispatching and constructor recursion delegating the recursion about rest... to a method (maybe static and also constexpr, if you want) used to initialize tmp



            class Counter
            {
            private:
            int count = 0;
            int tmp;

            static int getLastInt (int i)
            { return i; }

            template <typename ... Rest>
            static int getLastInt (int, Rest ... rs)
            { return getLastInt(rs...); }

            public:
            template <typename... Rest>
            Counter (Rest... rest)
            : count(sizeof...(Rest)), tmp{getLastInt(rest...)}
            { std::cout << tmp << ", " << count << "n"; }
            };


            Off Topic: to be precise, your Counter class isn't "a variadic template class".



            It's an ordinary (not template) class with one (two, in my first solution) variadic template constructor(s).



            -- EDIT --



            The OP asks




            What if I need to get the count as a static const variable and an int array with the length of the counter within compile time and as class members? (Array will be filled with all constructor arguments) Is this within the C++ possibilitys?




            A static const (maybe also constexpr) make sense only if the counter is a common value between all the instances of the class.



            At the moment doesn't make sense because your Counter accept initialization lists of different length.



            But suppose that number of the argument of the constructor is a template parameter (say N)... in that case count is simply N and can be static constexpr. You can define a std::array<int, N> for the values (also a int[N] but I suggest to avoid to use C-style arrays, when possible, and use std::array instead) and, making the constructor constexpr, you can impose the compile time initialization.



            The following is a full compiling C++14 example (uses std::make_index_sequence and std::index_sequence that, unfortunately, are available only starting from C++14).



            Observe that I've defined the f8 variable in main() as constexpr: only this way you can impose (pretending there isn't the as-is rule) that f8 is initialized compile-time



            #include <array>
            #include <iostream>
            #include <type_traits>

            template <typename T, std::size_t>
            using getType = T;

            template <std::size_t N, typename = std::make_index_sequence<N>>
            struct foo;

            template <std::size_t N, std::size_t ... Is>
            struct foo<N, std::index_sequence<Is...>>
            {
            static_assert( sizeof...(Is), "!" );

            static constexpr auto count = N;

            const std::array<int, N> arr;

            constexpr foo (getType<int, Is> ... is) : arr {{ is ... }}
            { }
            };

            int main ()
            {
            constexpr foo<8u> f8 { 2, 3, 5, 7, 11, 13, 17, 19 };

            for ( auto const & i : f8.arr )
            std::cout << i << ' ';

            std::cout << std::endl;
            }


            If you can use a C++17 enabled compiler, you can also use a deduction guide for foo



            template <typename ... Args>
            foo(Args...) -> foo<sizeof...(Args)>;


            so there is no needs to explicate the template argument defining f8



            // .......VVV  no more "<8u>"
            constexpr foo f3{ 2, 3, 5, 7, 11, 13, 17, 19 };


            because it's deduced from the number of the argument of the constructor.






            share|improve this answer


























            • Thank u very much for the hint, that helped a lot! What if I need to get the count as a static const variable and an int array with the length of the counter within compile time and as class members? (Array will be filled with all constructor arguments) Is this within the C++ possibilitys?

              – PrettyCoffee
              yesterday











            • @PrettyCoffee - Let me think... Take in count that a static variable is a variable common to all instances of the class, so a static count variable (constant, moreover) make sense only if the count value is common to all instances of Counter. At the moment do not make sense because you can call the constructor of different instances with different number of arguments. It's different if the number of the template argument is a template parameter of the class. Give me some minutes and I prepare an example of what I mean.

              – max66
              yesterday











            • @PrettyCoffee - answer improved; hope this helps.

              – max66
              yesterday
















            11














            As explained by VTT, calling Counter() inside the body of the constructor create a new Counter() object.



            You can call, recursively, the contructors but you have to do this in the initialization list: look for "delegating contructors" for more informations.



            I also would advise you against initialization (and modifications) of member object inside the body of contructors.



            If your target is initialize count with the number of the arguments and tmp with the value of the last argument, I propose the following ("tag dispatching" based) solution



            class Counter
            {
            private:
            struct tag
            { };

            int count = 0;
            int tmp;

            Counter (tag tg, std::size_t c0, int t) : count(c0), tmp{t}
            { std::cout << "end: " << tmp << ", " <<count << "n"; }

            template <typename... Rest>
            Counter (tag t0, std::size_t c0, int t, Rest... rest)
            : Counter{t0, c0, rest...}
            { std::cout << "recursion: " << tmp << ", " << count << "n"; }

            public:
            template <typename... Rest>
            Counter (Rest... rest) : Counter{tag{}, sizeof...(Rest), rest...}
            { std::cout << "start: " << tmp << ", " << count << "n"; }
            };


            You can also avoid tag-dispatching and constructor recursion delegating the recursion about rest... to a method (maybe static and also constexpr, if you want) used to initialize tmp



            class Counter
            {
            private:
            int count = 0;
            int tmp;

            static int getLastInt (int i)
            { return i; }

            template <typename ... Rest>
            static int getLastInt (int, Rest ... rs)
            { return getLastInt(rs...); }

            public:
            template <typename... Rest>
            Counter (Rest... rest)
            : count(sizeof...(Rest)), tmp{getLastInt(rest...)}
            { std::cout << tmp << ", " << count << "n"; }
            };


            Off Topic: to be precise, your Counter class isn't "a variadic template class".



            It's an ordinary (not template) class with one (two, in my first solution) variadic template constructor(s).



            -- EDIT --



            The OP asks




            What if I need to get the count as a static const variable and an int array with the length of the counter within compile time and as class members? (Array will be filled with all constructor arguments) Is this within the C++ possibilitys?




            A static const (maybe also constexpr) make sense only if the counter is a common value between all the instances of the class.



            At the moment doesn't make sense because your Counter accept initialization lists of different length.



            But suppose that number of the argument of the constructor is a template parameter (say N)... in that case count is simply N and can be static constexpr. You can define a std::array<int, N> for the values (also a int[N] but I suggest to avoid to use C-style arrays, when possible, and use std::array instead) and, making the constructor constexpr, you can impose the compile time initialization.



            The following is a full compiling C++14 example (uses std::make_index_sequence and std::index_sequence that, unfortunately, are available only starting from C++14).



            Observe that I've defined the f8 variable in main() as constexpr: only this way you can impose (pretending there isn't the as-is rule) that f8 is initialized compile-time



            #include <array>
            #include <iostream>
            #include <type_traits>

            template <typename T, std::size_t>
            using getType = T;

            template <std::size_t N, typename = std::make_index_sequence<N>>
            struct foo;

            template <std::size_t N, std::size_t ... Is>
            struct foo<N, std::index_sequence<Is...>>
            {
            static_assert( sizeof...(Is), "!" );

            static constexpr auto count = N;

            const std::array<int, N> arr;

            constexpr foo (getType<int, Is> ... is) : arr {{ is ... }}
            { }
            };

            int main ()
            {
            constexpr foo<8u> f8 { 2, 3, 5, 7, 11, 13, 17, 19 };

            for ( auto const & i : f8.arr )
            std::cout << i << ' ';

            std::cout << std::endl;
            }


            If you can use a C++17 enabled compiler, you can also use a deduction guide for foo



            template <typename ... Args>
            foo(Args...) -> foo<sizeof...(Args)>;


            so there is no needs to explicate the template argument defining f8



            // .......VVV  no more "<8u>"
            constexpr foo f3{ 2, 3, 5, 7, 11, 13, 17, 19 };


            because it's deduced from the number of the argument of the constructor.






            share|improve this answer


























            • Thank u very much for the hint, that helped a lot! What if I need to get the count as a static const variable and an int array with the length of the counter within compile time and as class members? (Array will be filled with all constructor arguments) Is this within the C++ possibilitys?

              – PrettyCoffee
              yesterday











            • @PrettyCoffee - Let me think... Take in count that a static variable is a variable common to all instances of the class, so a static count variable (constant, moreover) make sense only if the count value is common to all instances of Counter. At the moment do not make sense because you can call the constructor of different instances with different number of arguments. It's different if the number of the template argument is a template parameter of the class. Give me some minutes and I prepare an example of what I mean.

              – max66
              yesterday











            • @PrettyCoffee - answer improved; hope this helps.

              – max66
              yesterday














            11












            11








            11







            As explained by VTT, calling Counter() inside the body of the constructor create a new Counter() object.



            You can call, recursively, the contructors but you have to do this in the initialization list: look for "delegating contructors" for more informations.



            I also would advise you against initialization (and modifications) of member object inside the body of contructors.



            If your target is initialize count with the number of the arguments and tmp with the value of the last argument, I propose the following ("tag dispatching" based) solution



            class Counter
            {
            private:
            struct tag
            { };

            int count = 0;
            int tmp;

            Counter (tag tg, std::size_t c0, int t) : count(c0), tmp{t}
            { std::cout << "end: " << tmp << ", " <<count << "n"; }

            template <typename... Rest>
            Counter (tag t0, std::size_t c0, int t, Rest... rest)
            : Counter{t0, c0, rest...}
            { std::cout << "recursion: " << tmp << ", " << count << "n"; }

            public:
            template <typename... Rest>
            Counter (Rest... rest) : Counter{tag{}, sizeof...(Rest), rest...}
            { std::cout << "start: " << tmp << ", " << count << "n"; }
            };


            You can also avoid tag-dispatching and constructor recursion delegating the recursion about rest... to a method (maybe static and also constexpr, if you want) used to initialize tmp



            class Counter
            {
            private:
            int count = 0;
            int tmp;

            static int getLastInt (int i)
            { return i; }

            template <typename ... Rest>
            static int getLastInt (int, Rest ... rs)
            { return getLastInt(rs...); }

            public:
            template <typename... Rest>
            Counter (Rest... rest)
            : count(sizeof...(Rest)), tmp{getLastInt(rest...)}
            { std::cout << tmp << ", " << count << "n"; }
            };


            Off Topic: to be precise, your Counter class isn't "a variadic template class".



            It's an ordinary (not template) class with one (two, in my first solution) variadic template constructor(s).



            -- EDIT --



            The OP asks




            What if I need to get the count as a static const variable and an int array with the length of the counter within compile time and as class members? (Array will be filled with all constructor arguments) Is this within the C++ possibilitys?




            A static const (maybe also constexpr) make sense only if the counter is a common value between all the instances of the class.



            At the moment doesn't make sense because your Counter accept initialization lists of different length.



            But suppose that number of the argument of the constructor is a template parameter (say N)... in that case count is simply N and can be static constexpr. You can define a std::array<int, N> for the values (also a int[N] but I suggest to avoid to use C-style arrays, when possible, and use std::array instead) and, making the constructor constexpr, you can impose the compile time initialization.



            The following is a full compiling C++14 example (uses std::make_index_sequence and std::index_sequence that, unfortunately, are available only starting from C++14).



            Observe that I've defined the f8 variable in main() as constexpr: only this way you can impose (pretending there isn't the as-is rule) that f8 is initialized compile-time



            #include <array>
            #include <iostream>
            #include <type_traits>

            template <typename T, std::size_t>
            using getType = T;

            template <std::size_t N, typename = std::make_index_sequence<N>>
            struct foo;

            template <std::size_t N, std::size_t ... Is>
            struct foo<N, std::index_sequence<Is...>>
            {
            static_assert( sizeof...(Is), "!" );

            static constexpr auto count = N;

            const std::array<int, N> arr;

            constexpr foo (getType<int, Is> ... is) : arr {{ is ... }}
            { }
            };

            int main ()
            {
            constexpr foo<8u> f8 { 2, 3, 5, 7, 11, 13, 17, 19 };

            for ( auto const & i : f8.arr )
            std::cout << i << ' ';

            std::cout << std::endl;
            }


            If you can use a C++17 enabled compiler, you can also use a deduction guide for foo



            template <typename ... Args>
            foo(Args...) -> foo<sizeof...(Args)>;


            so there is no needs to explicate the template argument defining f8



            // .......VVV  no more "<8u>"
            constexpr foo f3{ 2, 3, 5, 7, 11, 13, 17, 19 };


            because it's deduced from the number of the argument of the constructor.






            share|improve this answer















            As explained by VTT, calling Counter() inside the body of the constructor create a new Counter() object.



            You can call, recursively, the contructors but you have to do this in the initialization list: look for "delegating contructors" for more informations.



            I also would advise you against initialization (and modifications) of member object inside the body of contructors.



            If your target is initialize count with the number of the arguments and tmp with the value of the last argument, I propose the following ("tag dispatching" based) solution



            class Counter
            {
            private:
            struct tag
            { };

            int count = 0;
            int tmp;

            Counter (tag tg, std::size_t c0, int t) : count(c0), tmp{t}
            { std::cout << "end: " << tmp << ", " <<count << "n"; }

            template <typename... Rest>
            Counter (tag t0, std::size_t c0, int t, Rest... rest)
            : Counter{t0, c0, rest...}
            { std::cout << "recursion: " << tmp << ", " << count << "n"; }

            public:
            template <typename... Rest>
            Counter (Rest... rest) : Counter{tag{}, sizeof...(Rest), rest...}
            { std::cout << "start: " << tmp << ", " << count << "n"; }
            };


            You can also avoid tag-dispatching and constructor recursion delegating the recursion about rest... to a method (maybe static and also constexpr, if you want) used to initialize tmp



            class Counter
            {
            private:
            int count = 0;
            int tmp;

            static int getLastInt (int i)
            { return i; }

            template <typename ... Rest>
            static int getLastInt (int, Rest ... rs)
            { return getLastInt(rs...); }

            public:
            template <typename... Rest>
            Counter (Rest... rest)
            : count(sizeof...(Rest)), tmp{getLastInt(rest...)}
            { std::cout << tmp << ", " << count << "n"; }
            };


            Off Topic: to be precise, your Counter class isn't "a variadic template class".



            It's an ordinary (not template) class with one (two, in my first solution) variadic template constructor(s).



            -- EDIT --



            The OP asks




            What if I need to get the count as a static const variable and an int array with the length of the counter within compile time and as class members? (Array will be filled with all constructor arguments) Is this within the C++ possibilitys?




            A static const (maybe also constexpr) make sense only if the counter is a common value between all the instances of the class.



            At the moment doesn't make sense because your Counter accept initialization lists of different length.



            But suppose that number of the argument of the constructor is a template parameter (say N)... in that case count is simply N and can be static constexpr. You can define a std::array<int, N> for the values (also a int[N] but I suggest to avoid to use C-style arrays, when possible, and use std::array instead) and, making the constructor constexpr, you can impose the compile time initialization.



            The following is a full compiling C++14 example (uses std::make_index_sequence and std::index_sequence that, unfortunately, are available only starting from C++14).



            Observe that I've defined the f8 variable in main() as constexpr: only this way you can impose (pretending there isn't the as-is rule) that f8 is initialized compile-time



            #include <array>
            #include <iostream>
            #include <type_traits>

            template <typename T, std::size_t>
            using getType = T;

            template <std::size_t N, typename = std::make_index_sequence<N>>
            struct foo;

            template <std::size_t N, std::size_t ... Is>
            struct foo<N, std::index_sequence<Is...>>
            {
            static_assert( sizeof...(Is), "!" );

            static constexpr auto count = N;

            const std::array<int, N> arr;

            constexpr foo (getType<int, Is> ... is) : arr {{ is ... }}
            { }
            };

            int main ()
            {
            constexpr foo<8u> f8 { 2, 3, 5, 7, 11, 13, 17, 19 };

            for ( auto const & i : f8.arr )
            std::cout << i << ' ';

            std::cout << std::endl;
            }


            If you can use a C++17 enabled compiler, you can also use a deduction guide for foo



            template <typename ... Args>
            foo(Args...) -> foo<sizeof...(Args)>;


            so there is no needs to explicate the template argument defining f8



            // .......VVV  no more "<8u>"
            constexpr foo f3{ 2, 3, 5, 7, 11, 13, 17, 19 };


            because it's deduced from the number of the argument of the constructor.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited yesterday

























            answered yesterday









            max66max66

            39.4k74575




            39.4k74575













            • Thank u very much for the hint, that helped a lot! What if I need to get the count as a static const variable and an int array with the length of the counter within compile time and as class members? (Array will be filled with all constructor arguments) Is this within the C++ possibilitys?

              – PrettyCoffee
              yesterday











            • @PrettyCoffee - Let me think... Take in count that a static variable is a variable common to all instances of the class, so a static count variable (constant, moreover) make sense only if the count value is common to all instances of Counter. At the moment do not make sense because you can call the constructor of different instances with different number of arguments. It's different if the number of the template argument is a template parameter of the class. Give me some minutes and I prepare an example of what I mean.

              – max66
              yesterday











            • @PrettyCoffee - answer improved; hope this helps.

              – max66
              yesterday



















            • Thank u very much for the hint, that helped a lot! What if I need to get the count as a static const variable and an int array with the length of the counter within compile time and as class members? (Array will be filled with all constructor arguments) Is this within the C++ possibilitys?

              – PrettyCoffee
              yesterday











            • @PrettyCoffee - Let me think... Take in count that a static variable is a variable common to all instances of the class, so a static count variable (constant, moreover) make sense only if the count value is common to all instances of Counter. At the moment do not make sense because you can call the constructor of different instances with different number of arguments. It's different if the number of the template argument is a template parameter of the class. Give me some minutes and I prepare an example of what I mean.

              – max66
              yesterday











            • @PrettyCoffee - answer improved; hope this helps.

              – max66
              yesterday

















            Thank u very much for the hint, that helped a lot! What if I need to get the count as a static const variable and an int array with the length of the counter within compile time and as class members? (Array will be filled with all constructor arguments) Is this within the C++ possibilitys?

            – PrettyCoffee
            yesterday





            Thank u very much for the hint, that helped a lot! What if I need to get the count as a static const variable and an int array with the length of the counter within compile time and as class members? (Array will be filled with all constructor arguments) Is this within the C++ possibilitys?

            – PrettyCoffee
            yesterday













            @PrettyCoffee - Let me think... Take in count that a static variable is a variable common to all instances of the class, so a static count variable (constant, moreover) make sense only if the count value is common to all instances of Counter. At the moment do not make sense because you can call the constructor of different instances with different number of arguments. It's different if the number of the template argument is a template parameter of the class. Give me some minutes and I prepare an example of what I mean.

            – max66
            yesterday





            @PrettyCoffee - Let me think... Take in count that a static variable is a variable common to all instances of the class, so a static count variable (constant, moreover) make sense only if the count value is common to all instances of Counter. At the moment do not make sense because you can call the constructor of different instances with different number of arguments. It's different if the number of the template argument is a template parameter of the class. Give me some minutes and I prepare an example of what I mean.

            – max66
            yesterday













            @PrettyCoffee - answer improved; hope this helps.

            – max66
            yesterday





            @PrettyCoffee - answer improved; hope this helps.

            – max66
            yesterday










            PrettyCoffee is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            PrettyCoffee is a new contributor. Be nice, and check out our Code of Conduct.













            PrettyCoffee is a new contributor. Be nice, and check out our Code of Conduct.












            PrettyCoffee is a new contributor. Be nice, and check out our Code of Conduct.
















            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%2f55665792%2fthe-variadic-template-constructor-of-my-class-cannot-modify-my-class-members-wh%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

            VNC viewer RFB protocol error: bad desktop size 0x0I Cannot Type the Key 'd' (lowercase) in VNC Viewer...

            Tribunal Administrativo e Fiscal de Mirandela Referências Menu de...

            looking for continuous Screen Capture for retroactivly reproducing errors, timeback machineRolling desktop...