CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Sep 2016
    Posts
    8

    Code Consolidation And Redundancy Involving Templates And Vectors

    Greetings all... Below I have a sample program with the headers and cpp files listed. As you can see in the main routine, there are 5 function calls that are all very similar. They call 5 corresponding routines in the Classrooms class. Can I solicit solutions to making this one call, with variables or templates to reduce the calls, or at least have a single call with typing? The only thing I can't change is the access of the vectors in the Classrooms.h.

    I've tried this with templates and to be honest **** near threw my keyboard through the monitor with frustration. Anybody can help?


    Names.h

    Code:
        class Names {
            public:
    
                enum class Enums : int { Jack, Jill, John, Judy, Jzee };
        };
    Names.cpp
    Code:
        #include "Names.h"
    Students.h

    Code:
        #include <algorithm>
        #include <condition_variable>
        #include "Names.h"
    
        template <Names::Enums name_a> class Students {
            public:
                Students();
                void PrintEnum();
        };
    
        template <Names::Enums name_a> Students<name_a>::Students() {
        }
    
        template <Names::Enums name_a> void Students<name_a>::PrintEnum() {
            printf("%s: Enum value for name = %d\n", __func__, (int) name_a);
        }
    Students.cpp
    Code:
        #include "Students.h"
    Classrooms.h

    Code:
        #include <algorithm>
        #include <condition_variable>
        #include "Names.h"
        #include "Students.h"
    
        class Classrooms {
            private:
                std::vector<std::unique_ptr<Students<Names::Enums::Jack>>> Jacks;
        
                std::vector<std::unique_ptr<Students<Names::Enums::Jill>>> Jills;
        
                std::vector<std::unique_ptr<Students<Names::Enums::John>>> Johns;
        
                std::vector<std::unique_ptr<Students<Names::Enums::Judy>>> Judys;
        
                std::vector<std::unique_ptr<Students<Names::Enums::Jzee>>> Jzees;
    
            public:
    
                Classrooms() { }
        
                Students<Names::Enums::Jack>* Get_a_Jack(int e) { return Jacks.at(e).get(); }
        
                Students<Names::Enums::Jill>* Get_a_Jill(int e) { return Jills.at(e).get(); }
        
                Students<Names::Enums::John>* Get_a_John(int e) { return Johns.at(e).get(); }
        
                Students<Names::Enums::Judy>* Get_a_Judy(int e) { return Judys.at(e).get(); }
        
                Students<Names::Enums::Jzee>* Get_a_Jzee(int e) { return Jzees.at(e).get(); }
        
        };
    Classrooms.cpp
    Code:
        #include "Classrooms.h"
    main.cpp

    Code:
        #include <algorithm>
        #include <condition_variable>
        #include "Names.h"
        #include "Classrooms.h"
    
        using namespace std;
    
        int main(int argc, char** argv) {
        
            Classrooms *cr = new Classrooms();
        
            cr->Get_a_Jack(0)->PrintEnum();
        
            cr->Get_a_Jill(0)->PrintEnum();
        
            cr->Get_a_John(0)->PrintEnum();
        
            cr->Get_a_Judy(0)->PrintEnum();
        
            cr->Get_a_Jzee(0)->PrintEnum();
    
            return 0;
        }

  2. #2
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Code Consolidation And Redundancy Involving Templates And Vectors

    Classrooms seems a very strange class where you have a private member variable for each of the values of Enums - and a getter function for each as well. What is trying to be achieved? Is this a homework assignment?

    Note that as the default constructor for Classrooms doesn't initialise the class variables, the Get_a_???(0) function calls try to access a non-existent vector element!
    Last edited by 2kaud; March 13th, 2017 at 08:13 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    Join Date
    Sep 2016
    Posts
    8

    Re: Code Consolidation And Redundancy Involving Templates And Vectors

    Quote Originally Posted by 2kaud View Post
    Classrooms seems a very strange class where you have a private member variable for each of the values of Enums - and a getter function for each as well. What is trying to be achieved? Is this a homework assignment?

    Note that as the default constructor for Classrooms doesn't initialise the class variables, the Get_a_???(0) function calls try to access a non-existent vector element!
    This is ONLY a sample bit of code. It is in no way representative of the actual code, which is way to complicated and sensitive in nature to be put in a post. Not to mention I never seem to get answers, just critiques over the sample. Students, name and classrooms is not the questions. I'm simply trying to find a cleaner way of condensing the 5 separate calls from main and the corresponding calls in Classrooms so that there aren't so many individual calls. Maybe one with a switch. But I can't seem to get it done.

  4. #4
    Join Date
    Feb 2017
    Posts
    677

    Re: Code Consolidation And Redundancy Involving Templates And Vectors

    Quote Originally Posted by Non Sequitur View Post
    I'm simply trying to find a cleaner way of condensing the 5 separate calls from main and the corresponding calls in Classrooms so that there aren't so many individual calls.
    I'm not sure I fully understand what you are asking but one way to use polymorphism in template code is by way of specialization. Here's a small example,

    Code:
    enum class Name {Jack, Jill};
    
    template <Name N> class Student {}; // class to be specialized
    
    template <> class Student<Name::Jack> { // specialized for Jack
    public:
    	void print() {std::cout << "Jack" << std::endl;}
    };
    
    template <> class Student<Name::Jill> { // specialized for Jill
    public:
    	void print() {std::cout << "Jill" << std::endl;}
    };
    
    class Classroom {
    public:
    	template <Name N>
    	auto get() {     // one common access method
    		return std::make_unique<Student<N>>();
    	}
    };
    
    void test() {
    	Classroom cr;
    	cr.get<Name::Jack>()->print(); // selection by template parameter
    	cr.get<Name::Jill>()->print();
    }
    Last edited by wolle; March 14th, 2017 at 02:25 AM.

  5. #5
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Code Consolidation And Redundancy Involving Templates And Vectors

    Quote Originally Posted by Non Sequitur View Post
    I'm simply trying to find a cleaner way of condensing the 5 separate calls from main and the corresponding calls in Classrooms so that there aren't so many individual calls.
    do you mean something like ?

    Code:
    template < Names::Enums Name >
    Students<Name>* Get(int e)
    {
            return std::get< std::vector<std::unique_ptr<Students<Name>>>& >( std::tie( Jacks, Jills, Johns, Judys, Jzees ) ).at(e).get();
    }
    not tested, requires c++14 <tuple>
    obviously, a c++11/03 solution is possible, but more convoluted. If you tell us what you're trying to do at a higher level we could be of more help ...
    Last edited by superbonzo; March 14th, 2017 at 12:45 PM. Reason: fixed missing '&'

  6. #6
    Join Date
    Sep 2016
    Posts
    8

    Re: Code Consolidation And Redundancy Involving Templates And Vectors

    Quote Originally Posted by superbonzo View Post
    do you mean something like ?

    Code:
    template < Names::Enums Name >
    Students<Name>* Get(int e)
    {
            return std::get< std::vector<std::unique_ptr<Students<Name>>> >( std::tie( Jacks, Jills, Johns, Judys, Jzees ) ).at(e).get();
    }
    not tested, requires c++14 <tuple>
    obviously, a c++11/03 solution is possible, but more convoluted. If you tell us what you're trying to do at a higher level we could be of more help ...
    Wow,this is exactly the kind of thing I was looking for! I can't say I understand it, but holy cow! And as if I can't be grateful, I'm going to ask one more question... is there a way to limit the range of the elements in the std::tie, let's say so that only Jills thru Judys are part of the equation? Without having to create another enumerated list? I'm going to have to study up on the std::tie. Never heard of it, but an awesome capability/feature!!!!!!!!!!!

  7. #7
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Code Consolidation And Redundancy Involving Templates And Vectors

    Quote Originally Posted by Non Sequitur View Post
    I'm going to have to study up on the std::tie. Never heard of it, but an awesome capability/feature!!!!!!!!!!!
    anyway, note that the type based std::get is avaliable from c++14 on only. BTW, I just noticed there's a typo in my post above, I missed an '&' in the std::get argument. it's fixed now.

  8. #8
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Code Consolidation And Redundancy Involving Templates And Vectors

    Quote Originally Posted by Non Sequitur View Post
    I'm going to ask one more question... is there a way to limit the range of the elements in the std::tie, let's say so that only Jills thru Judys are part of the equation? Without having to create another enumerated list?
    uhm, not with std::tie, you'll need to write some template metaprogramming to do that... or use some existing metaprogramming library, like boost mpl/fusion/hana ...

  9. #9
    Join Date
    Sep 2016
    Posts
    8

    Re: Code Consolidation And Redundancy Involving Templates And Vectors

    Quote Originally Posted by superbonzo View Post
    uhm, not with std::tie, you'll need to write some template metaprogramming to do that... or use some existing metaprogramming library, like boost mpl/fusion/hana ...

    Hey, Superbonzo... do you have a PayPal account? I'd like to send you $25 bucks for a fantastic, elegant answer. I implemented what you suggested with the appropriate changes to match the actual code) and it is running as expected. Not to mention I cleaned up over 1300 lines of code. My many thanks!!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured