Template declaration inside if statement [duplicate] - c++

Suppose I have a class template which have a member pData, which is an AxB array of arbitary type T.
template <class T> class X{
public:
int A;
int B;
T** pData;
X(int a,int b);
~X();
void print(); //function which prints pData to screen
};
template<class T>X<T>::X(int a, int b){ //constructor
A = a;
B = b;
pData = new T*[A];
for(int i=0;i<A;i++)
pData[i]= new T[B];
//Fill pData with something of type T
}
int main(){
//...
std::cout<<"Give the primitive type of the array"<<std::endl;
std::cin>>type;
if(type=="int"){
X<int> XArray(a,b);
} else if(type=="char"){
X<char> Xarray(a,b);
} else {
std::cout<<"Not a valid primitive type!";
} // can be many more if statements.
Xarray.print() //this doesn't work, as Xarray is out of scope.
}
As the instance Xarray is constructed inside of an if statement, I cannot use it anywhere else. I tried to make a pointer before the if statements but as the type of the pointer is unknown at that point, I did not succeed.
What would be a proper way of dealing with this kind of a problem?

The problem here is that X<int> and x<char> are completely unrelated types.
The fact that they are both a result of the same templated class won't help here.
I can see several solutions, but those depends on what you really need.
You could, for instance make the X<> instances derive from a common non-templated base class that has the print() method (eventually as a pure virtual). But before you do that, be sure that it makes sense on a functional level: one should use inheritance because it makes sense, not solely because of technical constraints. And if you do that, you probably will want to have a virtual destructor as well.
You could also bind and store a std::function<void ()> to the method you want to call, but ensure that the objects are still "alive" (they aren't in your current code: both the X<int> and X<char> are destroyed when they go out of scope, way before you actually call print()).
A final solution would be to make some variant type that is compatible with both X<int> and X<char> (boost::variant<> can help here). You could then write a visitor that implements the print() functionality for each type.
Picking the last solution, it would become something like:
typedef boost::variant<X<int>, X<char>> genericX;
class print_visitor : public boost::static_visitor<void>
{
public:
template <typename SomeType>
void operator()(const SomeType& x) const
{
// Your print implementation
// x is your underlying instance, either X<char> or X<int>.
// You may also make several non-templated overloads of
// this operator if you want to provide different implementations.
}
};
int main()
{
boost::optional<genericX> my_x;
if (type=="int") {
my_x = X<int>(a,b);
} else if(type=="char") {
my_x = X<char>(a,b);
}
// This calls the appropriate print.
if (my_x) {
boost::apply_visitor(print_visitor(), *my_x)
}
}
We actually lack the knowledge to give a definitive answer: if your classes are "entities", then you probably should go for inheritance. If they are more like "value classes", then the variant way might be more suited.

C++ is a statically typed language, meaning that you must know the type of objects at compile time. In this case you are basing the type of the object constructed on user input, so it's not possible to know the type at runtime.
The most common way to address this issue is to use dynamic polymorphism in which functions are invoked via a common interface using late binding. We accomplish this in C++ using virtual functions. For example:
struct IPrintable {
virtual void print() = 0;
};
template<class T>
class X : public IPrintable {
// Same code as you showed above.
};
int main() {
std::cout<<"Give the primitive type of the array"<<std::endl;
std::cin>>type;
std::unique_ptr<IPrintable> XArray;
if(type=="int"){
XArray.reset(new X<int>(a,b));
} else if(type=="char"){
XArray.reset(new X<char>(a,b));
} else {
std::cout<<"Not a valid primitive type!";
} // can be many more if statements.
Xarray->print() // this works now!
}
This solves the out of scope issue and allows you to print using the dynamic type of the XArray variable. Virtual functions are the secret sauce that make this possible.

Rather than trying to fit the templates into main I would go the opposite way than the rest of the suggestions... move the code out of main and into it's own (possibly templated) function that needs to deal with a single type:
template <typename T>
void generateAndPrint(int a, int b) {
X<T> x(a,b);
x.print();
}
int main() { ...
if (type=="int") generateAndPrint<int>(a,b);
else if (type=="char") generateAndPrint<char>(a,b);
else ...
}

If you want to work with different arrays, whatever their type, templates alone cannot help you. Currently, there is exactly no relationship between X<int> and X<char>.
If you want to treat them as two subtypes of a common type, you will have to use inheritance (and dynamically allocated variables). For instance, all X<T> may inherit the same base class, say Printable, and you can store the data in a unique_ptr<Printable>:
unique_ptr<Printable> r;
if(type=="int"){
r.reset(new X<int>(a,b));
} else if(type=="char"){
r.reset(new X<char>(a,b);
}
r->print();
But this is probably not the best design.
A probably better solution would be, instead of trying to work outside of the if, to move all the work inside of the if. In your simple example, this could be done by duplicating the call to print, but this is not pretty nice either. But, going toward this idea, we can create a template function that does the job:
template<class T>
void workWithType(int a, int b)
{
X<T> Xarray(a, b);
Xarray.print();
}
//...
if(type=="int"){
workWithType<int>(a,b);
} else if(type=="char"){
workWithType<char>(a,b);
}

Related

Static cast base to derived pointer and construct derived members

A minimal example of what I want: I have two classes
template<typename T>
struct General;
template<typename T>
struct Specific;
with Specific inheriting from General, but General calling a Specific member function in its constructor:
template<typename T>
struct Specific: public General<T> {
int y;
void compute() {
y=x;
this->x++;
}
};
template<typename T>
struct General {
int x;
General(int x) : x(x) { static_cast<Specific<T>*>(this)->compute(); };
};
The idea is that there is one General class and multiple specific ones, and which one to use is decided either at run time or compile time.
The code above compiles and runs correctly, even though y is never actually constructed. I think I get away with it because it's a primitive type, but if I use a more complicated y instead:
template<typename T>
struct Specific: public General<T> {
std::vector<int> y;
void compute() {
y={0}; //anything here
this->x++;
}
};
then the code still compiles, but when executing the line with the comment I get a read access violation error because y hasn't been constructed.
There is a way out of it, and that's to have the variable y in General as opposed to Specific. This works, but different implementations need different variables, and it's not very elegant to include lots of protected variables in General that are only used by one implementation each (although from a performance standpoint, I guess compilers remove unused member variables as long as that can be detected in compile-time correct?). So is there a better way to do it?
Edit: One possible way suggested by Scheff:
General(int x) : x(x) {
Specific<T> B;
B = static_cast<Specific<T>&>(*this);
B.compute();
*this = static_cast<General<T>&>(B);
}
"Upgrading" a base class to a derived class is not going to happen. If I say
General<int> g(5)
I asked for a General<int> and I will get a General<int>. A Specific<int> is not a General<int>, and it would be wrong for me to get one. Indeed, since your Specific is larger than General, constructing a Specific where a General is expected corrupts the stack, even in the first example with two ints.
Deciding which subclass of General to instantiate belongs outside of its constructor, period. The most obvious way to get there is to untangle the initialization into normal constructors:
template<typename T>
struct General {
int x;
General(int x) : x(x) { }
virtual ~General() { }
};
template<typename T>
struct Specific : General<T> {
int y;
Specific(int x) : General<T>(x), y(this->x++) { }
};
and to decide which one to actually instantiate in a free function:
template<typename T>
std::unique_ptr<General<T>> DecideGeneral(int x) {
if(foo) return std::make_unique<Specific<T>>(x);
// other cases...
else return std::make_unique<General<T>>(x);
}
int main() {
// interesting tidbit:
// a const std::unique_ptr<T> is basically just a T, as the lifetime of the
// pointed-to object is exactly the same as the pointer's (it can't move out)
// all accesses are still indirect though
const auto g = DecideGeneral<int>(5);
}

Storing multiple types into the same container [duplicate]

This question already has answers here:
Heterogeneous containers in C++
(7 answers)
Closed 8 years ago.
Introduction
Say I have the follow
class thing {
template<typename T> void method(T value) {}
}
What I want to do is to store whatever value is passed into value no matter what type into a std::vector or something and without turning this into a template class (because that doesn't solve my problem in anyway)
I want to be able to do this without using boost (as much i love boost i am not going to use it all the time)
Attempted Ideas
Void Pointer
My initial though is to use a void* however i would lose the type of the object and it could end up being unsafe.
Union/Struct
My next thought was to use a union/struct like the one below:
union type_wrapper {
int a;
char f;
/* etc, etc, etc */
}
However i would run into the same problem as I would have to track the type, so i make sure it remains the same when ever used.
Wrapper Class
Then next thing i attempted was a class that would return the type in a function call like so:
template<typename T>
class type_wrapper {
T getType() { return /* get value of type/pointer/object here */ }
/*Stored in some manner */
}
Problem with is the same thing as with just the type on its own in that it cannot be stored in a list called lets say std::list<AClass> when its of type std::list<BClass> or std::list<int> etc
Other thing
All other examples i have looked at have do what i am doing but are expect that you track the type of the object one way or another, or use boost.
tl;dr
What could i try doing so that i could pass a parameter of type int and storing into a std::list etc it while using the same template function to pass a parameter of type 'cheese' (an imaginary class dedicated to filling your programs with cheese) and storing it into the same list, etc
I don't know if this will solve your problem, but you can use some polymorphic type for the container, and encapsulate the object in a generic derived class, so calls to object's member functions from the derived class' member functions can have full type information (they will be specialized templates), but your "thing" won't be generic, and client code won't care (or even know) about this inhertance:
class Aux {
public:
virtual void DoSomething() =0 ;
};
template<typename T>
class AuxTemp : public Aux {
T *real_obj;
public:
AuxTemp(const T &obj) : real_obj(new T(obj)) {} // create
AuxTemp(const AuxTemp &other) : real_obj(new T(*other.real_obj)) { } // copy
AuxTemp(AuxTemp &&other) : real_obj(other.real_obj) { other.real_obj=nullptr; } // move
~AuxTemp() { delete real_obj; } // destroy
void DoSomething() override {
real_obj->DoSomething(); // here we call the method with full type information for real_obj
}
};
class Thing {
std::vector<Aux*> v;
public:
template<typename T> void Add(const T &value) {
v.push_back(new AuxTemp<T>(value));
}
void DoSomethingForAll() {
for(auto &x:v) x->DoSomething();
}
};
Yo can test this with:
class A {
public:
void DoSomething() { std::cout << "A"<< std::endl; }
};
class B {
public:
void DoSomething() { std::cout << "B"<< std::endl; }
};
int main(int argc, char *argv[]) {
Thing t;
t.Add(A{});
t.Add(B{});
t.DoSomethingForAll();
return 0;
}
For each new type you push to your vector, a new derived and specialized wrapper class is made by Add member function, so virtual table can handle calls to DoSomething in order to use the proper and full-aware-of-real-type version.
I think what I propose is a bizarre implementation "type-erasure" (you should google for this term to find more elaborated solutions).

How to get instance of class template out of the if statement? (C++)

Suppose I have a class template which have a member pData, which is an AxB array of arbitary type T.
template <class T> class X{
public:
int A;
int B;
T** pData;
X(int a,int b);
~X();
void print(); //function which prints pData to screen
};
template<class T>X<T>::X(int a, int b){ //constructor
A = a;
B = b;
pData = new T*[A];
for(int i=0;i<A;i++)
pData[i]= new T[B];
//Fill pData with something of type T
}
int main(){
//...
std::cout<<"Give the primitive type of the array"<<std::endl;
std::cin>>type;
if(type=="int"){
X<int> XArray(a,b);
} else if(type=="char"){
X<char> Xarray(a,b);
} else {
std::cout<<"Not a valid primitive type!";
} // can be many more if statements.
Xarray.print() //this doesn't work, as Xarray is out of scope.
}
As the instance Xarray is constructed inside of an if statement, I cannot use it anywhere else. I tried to make a pointer before the if statements but as the type of the pointer is unknown at that point, I did not succeed.
What would be a proper way of dealing with this kind of a problem?
The problem here is that X<int> and x<char> are completely unrelated types.
The fact that they are both a result of the same templated class won't help here.
I can see several solutions, but those depends on what you really need.
You could, for instance make the X<> instances derive from a common non-templated base class that has the print() method (eventually as a pure virtual). But before you do that, be sure that it makes sense on a functional level: one should use inheritance because it makes sense, not solely because of technical constraints. And if you do that, you probably will want to have a virtual destructor as well.
You could also bind and store a std::function<void ()> to the method you want to call, but ensure that the objects are still "alive" (they aren't in your current code: both the X<int> and X<char> are destroyed when they go out of scope, way before you actually call print()).
A final solution would be to make some variant type that is compatible with both X<int> and X<char> (boost::variant<> can help here). You could then write a visitor that implements the print() functionality for each type.
Picking the last solution, it would become something like:
typedef boost::variant<X<int>, X<char>> genericX;
class print_visitor : public boost::static_visitor<void>
{
public:
template <typename SomeType>
void operator()(const SomeType& x) const
{
// Your print implementation
// x is your underlying instance, either X<char> or X<int>.
// You may also make several non-templated overloads of
// this operator if you want to provide different implementations.
}
};
int main()
{
boost::optional<genericX> my_x;
if (type=="int") {
my_x = X<int>(a,b);
} else if(type=="char") {
my_x = X<char>(a,b);
}
// This calls the appropriate print.
if (my_x) {
boost::apply_visitor(print_visitor(), *my_x)
}
}
We actually lack the knowledge to give a definitive answer: if your classes are "entities", then you probably should go for inheritance. If they are more like "value classes", then the variant way might be more suited.
C++ is a statically typed language, meaning that you must know the type of objects at compile time. In this case you are basing the type of the object constructed on user input, so it's not possible to know the type at runtime.
The most common way to address this issue is to use dynamic polymorphism in which functions are invoked via a common interface using late binding. We accomplish this in C++ using virtual functions. For example:
struct IPrintable {
virtual void print() = 0;
};
template<class T>
class X : public IPrintable {
// Same code as you showed above.
};
int main() {
std::cout<<"Give the primitive type of the array"<<std::endl;
std::cin>>type;
std::unique_ptr<IPrintable> XArray;
if(type=="int"){
XArray.reset(new X<int>(a,b));
} else if(type=="char"){
XArray.reset(new X<char>(a,b));
} else {
std::cout<<"Not a valid primitive type!";
} // can be many more if statements.
Xarray->print() // this works now!
}
This solves the out of scope issue and allows you to print using the dynamic type of the XArray variable. Virtual functions are the secret sauce that make this possible.
Rather than trying to fit the templates into main I would go the opposite way than the rest of the suggestions... move the code out of main and into it's own (possibly templated) function that needs to deal with a single type:
template <typename T>
void generateAndPrint(int a, int b) {
X<T> x(a,b);
x.print();
}
int main() { ...
if (type=="int") generateAndPrint<int>(a,b);
else if (type=="char") generateAndPrint<char>(a,b);
else ...
}
If you want to work with different arrays, whatever their type, templates alone cannot help you. Currently, there is exactly no relationship between X<int> and X<char>.
If you want to treat them as two subtypes of a common type, you will have to use inheritance (and dynamically allocated variables). For instance, all X<T> may inherit the same base class, say Printable, and you can store the data in a unique_ptr<Printable>:
unique_ptr<Printable> r;
if(type=="int"){
r.reset(new X<int>(a,b));
} else if(type=="char"){
r.reset(new X<char>(a,b);
}
r->print();
But this is probably not the best design.
A probably better solution would be, instead of trying to work outside of the if, to move all the work inside of the if. In your simple example, this could be done by duplicating the call to print, but this is not pretty nice either. But, going toward this idea, we can create a template function that does the job:
template<class T>
void workWithType(int a, int b)
{
X<T> Xarray(a, b);
Xarray.print();
}
//...
if(type=="int"){
workWithType<int>(a,b);
} else if(type=="char"){
workWithType<char>(a,b);
}

Constructor Template

I have a class with several constructors. According to a parameter which is passed via argv to main() I would like to switch between the different constructors. The following simplified example works fine in the case where "obj" is changed to class and I use e.g. obj1->int and obj2->double. But what do I have to change to make the following code run using enum?
#include<iostream>
using namespace std;
enum obj{obj1,obj2};
template <obj T>
class A
{
public:
A(T);
private:
T t_;
};
template<obj T>
A<T>::A(T )
{}
template<>
A<obj1>::A(obj1 t):t_(t) {cout<<"case 1"<< endl;}
template<>
A<obj2>::A(obj2 t):t_(t) {cout<<"case 2"<< endl;}
int main()
{
obj test=obj1;
A<obj> a(test);
return 1;
}
Thank you for your help!
EDIT: It's clear that the code is wrong concerning type/value, but which mechanism can resemble such a switching of constructors?
You have to specialize on types, not on values. If you know the value at compile-time, you could use boost::mpl::int_ to do so. If you don't (like in your case), you'll have to live with plain old if.
I think the following is what you intended to do:
#include<iostream>
enum obj{obj1,obj2};
template<obj>
class A
{
public:
A();
private:
obj t_;
};
template<obj x>
A<x>::A() : t_(x){}
template<>
A<obj1>::A() : t_(obj1){ std::cout << "obj1\n"; }
template<>
A<obj2>::A() : t_(obj2){ std::cout << "obj1\n"; }
int main()
{
const obj x = obj1; // can only be used as the template argument below because it's a compile time constant
A<x> a;
return 0;
}
However this only works if you want to 'switch' on a compile time constant, and it sounds like you don't. You need to use a run time condition (if, switch, etc).
You are approaching the problem wrong. Templates are instantiated at compile-time so you can't choose a specialization based on a value that is present at runtime. Aside from other mistakes in your code this solution won't work.
A common solution to this kind of problem (creating different objects based on a parameter) is the abstract factory pattern. It means that you move the conditional constructing logic to a factory class and use virtual methods to avoid the need to write different code on the calling side (so essentially you make use of polymorphism).
You have to do something like this:
enum E
{
A,
B
};
template<E e>
struct A
{
};
template<>
struct A<E::A>
{
};
template<>
struct A<E::B>
{
};
int main()
{
A<E::B> ab;
}

Passing objects of different types with the same interface

I have a number of class, all with exactly the same interface. This interface defines a few methods, some of which are templated (the class itself may or may not be).
So the interface looks something like this
class MyClass
{
public:
void Func1();
template <typename T>
void Func2(T param);
};
I have a number of functions which take various objects which conform to this interface but want to avoid having to know the exact implementation at compile time.
Obviously, the default C++ solution would be to have a base type that all these classes derive from and pass around a pointer to that and have polymorphism do all the work.
The problem is that templated member functions cannot be virtual so this method cannot be used. I also want to avoid changing the current set of classes that follow this interface because there are a large number of them, some of which are defined outside the scope of my project.
The other solution is to template the functions that use these objects so they specialise for the right type. This could be a solution but due to legacy requirements templating a large number functions may not be possible (this is something I cannot do anything about as the client code isn't something I have responsibility for).
My initial thought was to provide some kind of carrier class which is type neutral and in effects wraps the common interface here and has a base interface class to pass around the internal type.
Something along the lines of
class MyInterface
{
public:
virtual void Func1() = 0;
};
template <typename T>
class MyImplementation
{
public:
virtual void Func1()
{
m_impl->Func1();
}
private:
T* m_impl;
};
But again the templated member functions seem to block this approach.
I looked at the boost::any and boost::function classes which I thought might offer some kind of solution but they don't seem to give me the right answer.
So, does anyone have any suggestions or work around on how to make this possible, if indeed it is? Personally I'm leaning towards having to template the various functions that require these objects - since that's the functionality templates provide - but thought it worth investigating first.
Thanks in advance
What's not entirely clear to me is how you're resolving the parameter T to Func2, do you need some kind of dynamic dispatch on that too, or is it known at compile time at the call site?
In the former case, it sounds like multimethods. In the latter, how about this variation on your interface idea:
#include <iostream>
template<class T> struct generic_delegate
{
virtual void call(T param) = 0;
};
template<class U, class T> class fn_delegate : public generic_delegate<T>
{
U* obj;
void (U::*fn)(T);
public:
fn_delegate(U* o, void (U::*f)(T)) :
obj(o), fn(f)
{}
virtual void call(T param)
{
(obj->*fn)(param);
}
};
class A
{
public:
template<class T> void fn(T param)
{
std::cout << "A: " << param << std::endl;
}
};
class B
{
public:
template<class T> void fn(T param)
{
std::cout << "B: " << param << std::endl;
}
};
template<class T, class U> generic_delegate<T>* fn_deleg(U* o)
{
return new fn_delegate<U, T>(o, &U::template fn<T>);
}
int main()
{
A a;
B b;
generic_delegate<int>* i = fn_deleg<int>(&a);
generic_delegate<int>* j = fn_deleg<int>(&b);
i->call(4);
j->call(5);
}
Obviously, the thing you'd be passing around are the generic delegate pointers.
If you use templates you need to know AT COMPILE TIME which type(s) you're using. That's just the nature of templates (templates look like code that's dynamic at runtime, but in reality it's just shorthand that tells the compiler what versions of the function to compile and include in the object code). Best case senario is something like this:
template <class T>
void DoSomethingWithMyInterface(MyInterface<T> X)
{
//do something
}
...
switch (MyObject.GetTypeCode())
{
case TYPE1: DoSomethingWithMyInterface<type1>(MyObject); break;
case TYPE2: DoSomethingWithMyInterface<type2>(MyObject); break;
case TYPE3: DoSomethingWithMyInterface<type3>(MyObject); break;
case TYPE4: DoSomethingWithMyInterface<type4>(MyObject); break;
}
I actually use this situation a lot. I write templated c++ code that does the processing for a dynamically typed language. That means that the top level language doesn't know the data types until run time, but I need to know them at compile time. So I create this "TypeSwitch" (I actually have a fancy reusable one). That looks at the datatypes at run time and then figures out which of the already compiled template functions to run.
Note - that this requires me knowing all the types I'm going to support before hand (and I do) and the switch statement actually causes the compiler to generate all of the code that could ever be executed. Then at runtime the right one is selected.