-
March 13th, 2017, 12:17 AM
#1
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
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;
}
-
March 13th, 2017, 08:09 AM
#2
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)
-
March 13th, 2017, 01:00 PM
#3
Re: Code Consolidation And Redundancy Involving Templates And Vectors
Originally Posted by 2kaud
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.
-
March 13th, 2017, 03:33 PM
#4
Re: Code Consolidation And Redundancy Involving Templates And Vectors
Originally Posted by Non Sequitur
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.
-
March 14th, 2017, 03:04 AM
#5
Re: Code Consolidation And Redundancy Involving Templates And Vectors
Originally Posted by Non Sequitur
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 '&'
-
March 14th, 2017, 12:20 PM
#6
Re: Code Consolidation And Redundancy Involving Templates And Vectors
Originally Posted by superbonzo
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!!!!!!!!!!!
-
March 14th, 2017, 12:45 PM
#7
Re: Code Consolidation And Redundancy Involving Templates And Vectors
Originally Posted by Non Sequitur
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.
-
March 14th, 2017, 12:49 PM
#8
Re: Code Consolidation And Redundancy Involving Templates And Vectors
Originally Posted by Non Sequitur
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 ...
-
March 14th, 2017, 04:05 PM
#9
Re: Code Consolidation And Redundancy Involving Templates And Vectors
Originally Posted by superbonzo
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|