Structure and template class in C++ - c++

My task is to create a priority queue template class and show its work using different data types: int, string and any struct. I have to add, delete, print a specific element.
The class is:
template< class Type >
class PriorityList
{
private:
List<Type> elems;
As a struct I picked was this:
struct SOMESTRUCT
{
int num;
char word[];
};
As I understand a template class is a universal class which can be used for any incoming data type. I can see how to create the class for int and char [], but how do I make it work for struct too? Since you can't just write cout<< struct, neither cin>>... I'd have to create another function for inputting/outputting my struct, but if I put it in my template class, the class wouldn't be universal again.
What do I do? Also, do I have to make template or leave just one typename?

You can use
template<typename C>
class PriorityList
{
// ...
};
for any type C, including int, char, SOMESTRUCT. I would recommend against using cin and cout in your template, since it makes it harder to use for any class. You would need to overload operator<< and operator>> for each class you use, which might be tricky.
Instead you should just define some simple member functions. I would try to copy the style of std::queue<T>, since people will be familiar with it.
For example:
template<typename C>
class PriorityQueue
{
public:
void push(const C& item, int priority=0){
// ...
}
C& front(){
// ...
}
// and other required functions
};
Once it is defined, you can test it for different classes however you want. You can e.g. create a main() to declare a PriorityQueue<int>, read some ints from std::cin and then call those functions you defined, or you can just declare some instances of SOMESTRUCT and pass them into a PriorityQueue<SOMESTRUCT>.
In a real-life project you would probably use a proper unit testing framework such as catch for this purpose, which would automatically check everything works.

Related

in C++, I would like to define a class object from a template, by using a typename information coming from a variable(e.g. string)

In C++, I would like to define a class object from a template, by using a typename information coming from a variable(e.g. string).
E.g. this is the template class:
template<typename mtype>
class MyClass{
private:
mtype *a;
public:
....
}
And this is how I would like to use it:
void main()
{
....
// read information from external sources, e.g. config file
std::string mtype_info=ReadFromConfigFile();
// create a MyClass object, using the translation function my_trans()
MyClass<my_trans(mtype_info)> m;
}
Is something like this possible ?
Edit:
Thank you very much for the answers so far. I am already a few steps ahead in my thinking than I was before. I can try to provide some more context here.
MyClass is a wrapper for boost-library random probability distribution object. MyClass allows for different classes of probability distributions ( e.g. boost::random::normal_distribution, boost::random::binomial_distribution, boost::random::beta_distribution) to be created as an "abstract" MyClass object, such that once the MyClass object is initialized, it can be used in the same way in the code.
template<typename mtype>
class MyClass{
private:
mtype* a;
public:
template<typename... Args>
MyClass(Args&&... args) {
a = new mtype{ std::forward<Args>(args)... };
}
~probability_distribution() {
delete a;
}
template<typename Engine, typename Seeder>
friend class random_engine;
};
And the usage is:
MyClass<boost::random::normal_distribution<double>> m1(1,2);
MyClass<boost::random::beta_distribution<double>> m2(2,4);
...
double r1 = g_rand.get(m1);
double r2 = g_rand.get(m2);
Now want I want is that the actual distribution type (the boost class reference and initialization parameters) to come from a configuration file.
Templates need to be instantiated at compile time before you can do something with them. They are just templates. You could write some mapping of strings to already instantiated types. The following solution assumes that you can refactor MyClass<T> to have a common base:
struct MyClassBase {
virtual ~MyClassBase(){}
};
template<typename mtype>
class MyClass : public MyClassBase {
mtype *a;
};
Then you can write a function that returns an instance of the desired instantiation of MyClass:
std::unique_ptr<MyClassBase> make_MyClass(const std::string& s) {
if ( s == "string") { return std::unique_ptr<MyClassBase>(new MyClass<std::string>()); }
else if ( s == "int") { return std::unique_ptr<MyClassBase>(new MyClass<int>()); }
}
This only works for a limited number of types (while the MyClass template in principle can take any template parameter).
PS: It is not really clear why MyClass is a tempalte. If the motivation for this was to be able to choose the type of mytype at runtime, then it was the wrong approach.
Templates are extracted compile-time. The variable's value can be changed runtime, so you can't use it as a template argument.

C++ making a template class as place holder in another class

I am trying to make a template class as placeholder class which can hold something like and string and type T object. Below is the code which I have written for the same.
#include <iostream>
#include <string>
#include <map>
using namespace std;
//A class which act as placeholder to hold
//unknown object. Something similar as Object
//in Java
template <typename T>
class Genric
{
public:
map<string, T> addP; //This will be placeholder for time
// being.
};
class A
{
public:
Genric t1; //Have object of Genric class so that we can
// access the member variable in future.
void foo()
{
cout<<"Calling foo"<<endl;
}
};
int main()
{
A a1;
a1.foo();
}
But when I tried to compile I am getting below error.
$ g++ tempClass.cxx
tempClass.cxx:21:9: error: invalid use of template-name 'Genric' without an argument list
The purpose of above Genric class is just to act as placeholder class for one of the member variables which can be populated in future.
So is there a way we can write such Genric class.
You are defining Genric as a template class, but then trying to initialize t1 without giving a type to it. That is the error you are getting. Try for example:
Genric<int> t1;
Or, if you are looking for a truly runtime generic, look into boost::any.
You need something like boost::any:
map<string, boost::any> anywayzz;
You can store any object in it. You don't need Genric class template.
If you're not using boost, then you can implement any yourself. Look for its implementation, or type-erasure, on this site. You will surely get some idea. Start from here:
Type erasure techniques
A template is "generic" until the program is compiled. At that point the compile must be made aware of what types it has to deal with.
If you want something that can contain a compile-time unknown (better: not yet known) type template are not the solution. Since the actual type will be known just at runtime, you have to go towards runtime-based polymorphism (inheritance from a polymorphic base) eventually wrapped inside an "handler".
In essence you need a base with at leas t a virtual function that allow you to check the type, and generic derived class that implement that function in a suitable way for all types.
boost::any can be an implementation, but there can be simpler ways, especially considering that "a function that allows to discover a runtime type" is no more than ... dynamic_cast.
You can so cometo a solution like this
#include <memory>
class any_value
{
template<class T>
class wrapper; //see below
class common_base
{
public:
virtual ~common_base() {} //this makes the type polymorphic
template<class T>
T* has_value()
{
auto* ptr = dynamic_cast<wrapper<T>*>(this);
return ptr? &ptr->m: nullptr;
}
};
template<class T>
class wrapper: public common_base
{
public:
wrapper() :m() {}
wrapper(const T& t) :m(t) {}
T m;
};
std::unique_ptr<common_base> pb;
public:
any_value() {}
template<class T>
any_value(const T& t) :pb(new wrapper<T>(t)) {}
template<class T>
any_value& operator=(const T& t)
{ pb = std::unique_ptr<common_base>(new wrapper<T>(t)); return *this; }
any_value(any_value&&) =default;
any_value& operator=(any_value&&) =default;
//NOW THE GETTERS
template<class T>
T* get() const //nullptr if not holding a T*
{ return bool(pb)? pb->has_value<T>(): nullptr; }
template<class T>
bool get(T& t)
{
T* pt = get<T>();
if(pt) t = *pt;
return bool(pt);
}
};
#include <iostream>
#include <string>
int main()
{
any_value a(5), b(2.7192818), c(std::string("as a string"));
int vi=0; double vd=0; std::string vs;
if(!a.get(vi)) vi=0; //will go
if(!a.get(vd)) vd=0; //will fail
if(!a.get(vs)) vs.clear(); //will fail
std::cout <<"vi = "<<vi<<", vd = "<<vd<<", vs = "<<vs<<" \n";
if(!b.get(vi)) vi=0; //will fail
if(!b.get(vd)) vd=0; //will go
if(!b.get(vs)) vs.clear(); //will fail
std::cout <<"vi = "<<vi<<", vd = "<<vd<<", vs = "<<vs<<" \n";
if(!c.get(vi)) vi=0; //will fail
if(!c.get(vd)) vd=0; //will fail
if(!c.get(vs)) vs.clear(); //will go
std::cout <<"vi = "<<vi<<", vd = "<<vd<<", vs = "<<vs<<" \n";
}
Following Abhinav comment:
Since the C++ type system is static, you cannot -in general- deserialize an "unknown", unless you first deserialize something that can be "Known".
For this you first need a way to represet a C++ type (not object) into an recognizable value (sort of type-uid), and a "factory" that creates the wrappers appropriated for those "values".
On saving, you just save that uid, then ask via a common_base virtual function to save the wrapped value.
On loading, you first load the uid, than create a new wrapper with appropriate type (see after) and than load the value via a common_base virtual function.
To create an appropriate wrapper, you need a table that maps the uid-s towards functions that create the wrapper associated with the type uid.
This table must be pre-initialized for all the types you need to be able to serialize / deserialize.
But this goes long away your original question, that doesn't speak about serialization/deserialization.
If the problem is "serialization", the "type erasure" is not a complete solution. You should much more look at the "factory pattern". And post another question better suited for that argument.

Allowing access to private members

This question is somewhat a continuation of this one I've posted.
What I was trying to do: my point was to allow access to private members of a base class A in a derived class B, with the following restraints:
what I want to access is a structure -- an std::map<>, actually --, not a method;
I cannot modified the base class;
base class A has no templated method I may overload as a backdoor alternative -- and I would not add such method, as it would be going against the second restraint.
As a possible solution, I have been pointed to litb's solution (post / blog), but, for the life of me, I haven't been able to reach an understanding on what is done in these posts, and, therefore, I could not derive a solution to my problem.
What I am trying to do: The following code, from litb's solution, presents an approach on how to access private members from a class/struct, and it happens to cover the restrictions I've mentioned.
So, I'm trying to rearrange this one code:
template<typename Tag, typename Tag::type M>
struct Rob {
friend typename Tag::type get(Tag) {
return M;
}
};
// use
struct A {
A(int a):a(a) { }
private:
int a;
};
// tag used to access A::a
struct A_f {
typedef int A::*type;
friend type get(A_f);
};
template struct Rob<A_f, &A::a>;
int main() {
A a(42);
std::cout << "proof: " << a.*get(A_f()) << std::endl;
}
To something that would allow me to do the following -- note I'm about to inherit the class, as the entries in the std::map<> are added right after the initialization of the derived class B, i.e., the std::map<> isn't simply a static member of class A with a default value, so I need to access it from a particular instance of B:
// NOT MY CODE -- library <a.h>
class A {
private:
std::map<int, int> A_map;
};
// MY CODE -- module "b.h"
# include <a.h>
class B : private A {
public:
inline void uncover() {
for (auto it(A_map.begin()); it != A_map.end(); ++it) {
std::cout << it->first << " - " << it->second << std::endl;
}
}
};
What I'd like as an answer: I'd really love to have the above code working -- after the appropriate modifications --, but I'd be very content with an explanation on what is done in the first code block -- the one from litb's solution.
The blog post and its code is unfortunately a bit unclear. The concept is simple: an explicit template instantiation gets a free backstage pass to any class, because
An explicit instantiation of a library class may be an implementation detail of a client class, and
Explicit instantiations may only be declared at namespace scope.
The natural way to distribute this backstage pass is as a pointer to member. If you have a pointer to a given class member, you can access it in any object of that class regardless of the access qualification. Fortunately, pointer-to-members can be compile-time constants even in C++03.
So, we want a class which generates a pointer to member when it's explicitly instantiated.
Explicit instantiation is just a way of defining a class. How can merely generating a class do something? There are two alternatives:
Define a friend function, which is not a member of the class. This is what litb does.
Define a static data member, which gets initialized at startup. This is my style.
I'll present my style first, then discuss its shortcoming, and then modify it to match litb's mechanism. The end result is still simpler than the code from the blog.
Simple version.
The class takes three template arguments: the type of the restricted member, its actual name, and a reference to a global variable to receive a pointer to it. The class schedules a static object to be initialized, whose constructor initializes the global.
template< typename type, type value, type & receiver >
class access_bypass {
static struct mover {
mover()
{ receiver = value; }
} m;
};
template< typename type, type value, type & receiver >
typename access_bypass< type, value, receiver >::mover
access_bypass< type, value, receiver >::m;
Usage:
type_of_private_member target::* backstage_pass;
template class access_bypass <
type_of_private_member target::*,
& target::member_name,
backstage_pass
>;
target t;
t.* backstage_pass = blah;
See it work.
Unfortunately, you can't rely on results from this being available for global-object constructors in other source files before the program enters main, because there's no standard way to tell the compiler which order to initialize files in. But globals are initialized in the order they're declared, so you can just put your bypasses at the top and you'll be fine as long as static object constructors don't make function calls into other files.
Robust version.
This borrows an element from litb's code by adding a tag structure and a friend function, but it's a minor modification and I think it remains pretty clear, not terribly worse than the above.
template< typename type, type value, typename tag >
class access_bypass {
friend type get( tag )
{ return value; }
};
Usage:
struct backstage_pass {}; // now this is a dummy structure, not an object!
type_of_private_member target::* get( backstage_pass ); // declare fn to call
// Explicitly instantiating the class generates the fn declared above.
template class access_bypass <
type_of_private_member target::*,
& target::member_name,
backstage_pass
>;
target t;
t.* get( backstage_pass() ) = blah;
See it work.
The main difference between this robust version and litb's blog post is that I've collected all the parameters into one place and made the tag structure empty. It's just a cleaner interface to the same mechanism. But you do have to declare the get function, which the blog code does automatically.
OK, so you asked about how to make that weird "Rob" code work with your use case, so here it is.
// the magic robber
template<typename Tag, typename Tag::type M>
struct Rob {
friend typename Tag::type get(Tag) {
return M;
}
};
// the class you can't modify
class A {
private:
std::map<int, int> A_map;
};
struct A_f {
typedef std::map<int, int> A::*type;
friend type get(A_f);
};
template struct Rob<A_f, &A::A_map>;
class B : private A {
public:
inline void uncover() {
std::map<int, int>::iterator it = (this->*get(A_f())).begin();
}
};
Now, I personally think the cure here may be worse than the disease, despite that I'm usually the last one you'll see claiming that abusing C++ is OK. You can decide for yourself, so I've posted this as a separate answer from my one using the preprocessor to do it the old-school way.
Edit:
How It Works
Here I will replicate the code above, but with the types simplified and the code drawn out more, with copious comments. Mind you, I did not understand the code very well before I went through this exercise, I don't understand it completely now, and I certainly won't remember how it works tomorrow. Caveat maintainer.
Here's the code we aren't allowed to change, with the private member:
// we can use any type of value, but int is simple
typedef int value_type;
// this structure holds value securely. we think.
struct FortKnox {
FortKnox() : value(0) {}
private:
value_type value;
};
Now for the heist:
// define a type which is a pointer to the member we want to steal
typedef value_type FortKnox::* stolen_mem_ptr;
// this guy is sort of dumb, but he knows a backdoor in the standard
template<typename AccompliceTag, stolen_mem_ptr MemPtr>
struct Robber {
friend stolen_mem_ptr steal(AccompliceTag) {
return MemPtr; // the only reason we exist: to expose the goods
}
};
// this guy doesn't know how to get the value, but he has a friend who does
struct Accomplice {
friend stolen_mem_ptr steal(Accomplice);
};
// explicit instantiation ignores private access specifier on value
// we cannot create an object of this type, because the value is inaccessible
// but we can, thanks to the C++ standard, use this value in this specific way
template struct Robber<Accomplice, &FortKnox::value>;
// here we create something based on secure principles, but which is not secure
class FortKnoxFacade : private FortKnox {
public:
value_type get_value() const {
// prepare to steal the value
// this theft can only be perpetrated by using an accomplice
stolen_mem_ptr accessor = steal(Accomplice()); // it's over now
// dereference the pointer-to-member, using this as the target
return this->*accessor;
}
};
int main() {
FortKnoxFacade fort;
return fort.get_value();
}
How about something more brutal?
// MY CODE -- module "b.h"
# define private protected
# include <a.h>
# undef private
class B : private A {
// now you can access "private" members and methods in A
The best-packaged version I know of this idiom is as follows:
template<class Tag,typename Tag::type MemberPtr>
struct access_cast{
friend typename Tag::type get(Tag){return MemberPtr;};
};
template<class Tag,class MemberPtr>
struct access_tag{
typedef MemberPtr type;
friend type get(Tag);
};
class A {
public:
auto x() const {return x_;};
private:
int x_ = 9;
};
#include <iostream>
struct AMemTag: access_tag<AMemTag,int A::*>{}; //declare tag
template struct access_cast<AMemTag,&A::x_>; //define friend get function
int main() {
A a;
std::cout<<a.x()<<"\n";
a.*get(AMemTag()) = 4; //dereference returned member pointer and modify value
std::cout<<a.x()<<"\n";
}
See it work.

Container implementation for complex type

I'm trying to come up with a container wrapper which stores data of the following types: bool, int, double, std::string. In addition I have a complex type which I need to store in the container. Let's call it Foo. For the sake of simplicity we'll say that Foo contains a list of ints.
My container class currently wraps an ugly and complex container type which I get from a c api. When I'm finish manipulating the data in the container, I need to copy it back to the api. It uses unions and linked lists. It is possible that I can copy this data into, for example, a std::list, but this might cause performance issues which present themselves at a later date. Therefore, my container class is not dependant on how data is actually stored in memory.
Here's a quick idea of how my container looks:
template <class T>
class Cont
{
public:
Cont(ISetter<T>* setter)
: _setter(setter)
{
}
void sillyFunction(T t)
{
(*_setter)(t,0);
}
private:
...
ISetter<T>* _setter;
};
So I use a helper setter class which handles the nitty gritty of the memory. I have a number of these class but the ISetter will give you an idea of what I'm doing.
In order to deal with the Foo type, which is also stored by the c api in a rather bizarre way, I have arrived at the following setter. Again, this is just a rough example.
class IFoo
{
public:
virtual int getMember() = 0;
};
class Foo2: public IFoo
{
public:
virtual int getMember(){ return 1;} // dummy
};
template<typename T> class ISetter{};
template<> class ISetter<IFoo*>
{
public:
virtual void operator()(IFoo* value, int index) = 0;
};
template<typename T> class Setter{};
template<> class Setter2<Foo2*>: public ISetter<IFoo*>
{
public:
virtual void operator()(IFoo* value, int index)
{
_list[index] = dynamic_cast<Foo2*>(value);
}
private:
std::vector<Foo2*> _list;
};
So I handle my Foo as an interface called IFoo. The Setter2 implementation deals with the setting in memory of my list of Foos. Setter1, missing below, deals with the ugly c api memory.
Here's an idea of these class in practice:
Foo2* f = new Foo2();
ISetter<IFoo*>* setter = new Setter2<Foo2*>();
Cont<IFoo*>* container = new Cont<IFoo*>(setter);
container->sillyFunction(f);
When dealing with ints, for example, I do something like this instead:
int i = 10;
ISetter<int>* setter = new Setter1<int>();
Cont<int>* container = new Cont<int>(setter);
container->sillyFunction(i);
So, my question is if you think this is a good approach and what improvements you might recommend.
I use shared pointers instead of raw pointers.
I would create a single simple Foo wrapper class which can look up members data from the C API, and present it as a coherent class. No need for messing about with interfaces, virtual functions or inheritance for that. Just a single class will do.
So for each "Foo"-entry in the C API, you create a single Foo wrapper.
Then you have simple, well-behaved type representing individual instances of the data stored in your C library.
Now just take that and put it in a std::vector.
struct Foo {
Foo(<handle-or-pointer-to-library-data>);
// member functions for retrieving member data from the C API
};
std::vector<int>
std::vector<bool>
std::vector<std::string>
std::vector<Foo>
As I understand your problem, that would be a simple and efficient solution.
I would change it a little. Consider to remove all this Setter virtual-ism from your code. One of goal to introduce Templates were to have alternative to virtual-ism:
template <class T, class Setter>
class Cont
{
public:
Cont(Setter setter = Setter())
: _setter(setter)
{
}
void sillyFunction(T t)
{
_setter(t,0);
}
private:
...
Setter _setter;
};
And its simple usage:
template <class IType, class Type>
class Setter2_Virtual
{
public:
void operator()(IType* value, int index)
{
_list[index] = dynamic_cast<Type*>(value);
}
private:
std::vector<Type*> _list;
};
Cont<IFoo*, Setter2_Virtual<IFoo, Foo2> > container;
container.sillyFunction(f);
I concentrated on Setters - but maybe you can do the same with IFoo/Foo stuff as well.
Just an idea - you do not obliged to use it after all.

Dedicating a field in arbitrary class types for "external use"

My container needs to store a little information about its elements. Normally, I store this separately from elements. However, I'd like to give users possibility to conserve memory by dedicating a field in element structure type for external use. E.g.:
struct MyStuff
{
int foo;
char bar;
mutable char dedicated_for_external_use; // Because of alignment, this field
// won't increase sizeof (MyStuff)
};
The idea here is that the field must not be accessed by anything but element's container. Since containers store a copy (much like std::vector), it wouldn't be a problem if you added any given value x to several containers.
How would you design an interface for this that, if possible, would meet the following requirements?
Should be completely optional. I.e. it should be possible to automatically determine if given type provides such a field or not and then container would only use it if available.
Ideally, wouldn't depend on type traits etc. as I need maximum compiler compatibility.
Should be easy to use. I.e. if you can and want to enable this optimization for type MyStuff, you could do it with 3 lines of code, not 25. Internal complications, on the other hand, don't matter.
Should preferably exclude false positives completely. What I mean is: if you check for field foo_bar there is a small posibility that such field exists for a completely unrelated reason (and I think duck-typing is simply not for C++). A better way would be to check if type inherits marker class ProvidesExternalUseField from my library, as this can't be by accident.
EDIT
I know about Boost.Intrusive, but what I want is something different. If I go that way and create a hooks class with a single char field, it cannot be used to conserve memory in many cases. If inherited type has an int as first field, char field will be padded to 4 bytes. I.e. you'd often need intricate knowledge of type internals to be able to "squeeze" such extern-use field in, but inheritance doesn't really provide it:
struct hooks { mutable char dedicated_for_external_use; };
struct MyStuff : hooks
{
int foo;
char bar;
};
Here, size of MyStuff will be 12 bytes, not 8.
You can use partial template specialization for the case your data struct derives from the marker interface.
Let's say your marker interface class looks like this:
class ProvidesExternalUseField
{
public:
char GetExtraField () { return 0; }
void SetExtraField (char newVal) {}
};
It is not virtual for a purpose: we wouldn't want to add a vtable pointer to a data class just for this.
Now let's implement a simple container class:
template <class T>
class Container
{
public:
char GetExtraValue ()
{
return 0; // here we cannot know if T is derived from the marker
}
private:
T m_t;
};
And here is how we change it to distinguish between the 2 cases:
template <class T, bool DoesTProvideExternalUseField>
class ContainerImpl
{
public:
char GetExtraValue () { return 0; }
private:
T m_t;
};
template <class T>
class ContainerImpl<T, true>
{
public:
char GetExtraValue () { return m_t.GetExtraField(); }
private:
T m_t;
};
template <class T>
class Container: public ContainerImpl<T,
boost::is_base_of<ProvidesExternalUseField,T>::value>
{
};
Now you can define the structs like this:
struct A
{
int m_intVal;
};
struct B: public ProvidesExternalUseField
{
char GetExtraField () { return m_extraField; }
void SetExtraField (char newVal) { m_extraField = newVal; }
int m_intVal;
char m_charVal;
char m_extraField;
};
And use the container class in the exact same way:
Container<A> a;
Container<B> b;
You can also further automate (templatize) getters and setters in the marker interface by using a poiter-to-member as a template parameter.