Instantiate template using dynamic bool variable - c++

I want to return a type from function depending on a boolean flag. The idea was to create instances of a Test class later in the program operating with this traits structure that would hold the actual type. However, now I don't know what the return type of a traits function would be.
class Test {
public:
template <typename T>
class Traits {
public:
typedef T type;
};
...
};
??? Test::Options::traits(){
if(timer){
return Test::Traits<Timeable<Test>>();
} else {
return Test::Traits<Test>();
}
}

A function can only return one specific type.
There is no way in C++ to overload on return type.
You cannot dynamically change the return type of a function.

What you are looking for is runtime polymorphism, while C++ templates are compile-time polymorphism.
How are you going to use the return value? something like if (its type is something) ... else ... ? In this case you can use std::variant (C++17).
Or are you going to just call its methods that will be present in all variants? In this case you can use good old inheritance. Extract a common interface to a pure abstract class (often called "interface" anyway), derive from it all types you'd like to return. Ah, and don't return it by value. You can return e.g. std::unique_ptr<YourInterfaceType> (fits your example though involves dynamic memory allocation), or any other kind of reference

Related

C++: Create instance of templated class based on enum values

(How) is it possible to write a function that instantiates a template class based on input values? For example, given the template class:
template <typename T>
class Container {
T value;
};
I would need a function like
Container<?> convert(void* value, DataType data_type) {
switch (data_type) {
case INT32: {
Container<int32_t> cnt;
cnt.value = static_cast<int32_t>(value);
return cnt;
}
...
}
}
and use it as follows:
void* value;
DataType data_type; // enum: can be INT32, INT64, ...
do_something(value, &data_type); // some C function
Container<?> cnt = convert(value, data_type);
You don't need an enum for this. You can just use the type itself:
template <class T>
Container<To> convert(void* value)
{
Container<T> cnt{};
cnt.value = *static_cast<T*>(*value);
return cnt;
}
with usage:
void* value;
do_something(value, &data_type); // some C function
Container<int32_t> cnt = convert_to<int_32>(value);
The C function I'm using defines this enum and gives me a data type.
Is it right that I cannot get around a solution where the user of my
(wrapper) function has to know the return type?
Correct. The value of the enum is known at runtime while the template parameter for Container must be known at compile time. So you cannot determine the type of Container from data_type.
There is something you can do though. You can use std::variant, but I don't go into it here.
To achieve this you have to map an enum with a type. Instantiation implies this to happen at runtime, which requires some kind of RTTI, be it built in or self made (e.g using the typeid operator, or a std::type_info::hash_code based on that).
If you say enum this implies a finite, known set of to be expected types.
The easiest way is to have a non templated base class
from which the templated ones inherit.
class Container_base {};
template <typename T>
class Container : public Container_base {
T value;
};
Your factory function convert can then cast, or instantiate dynamically base class pointers.
Container_base* convert(void* value, DataType data_type) {
switch (data_type) {
case INT32: {
return new Container<int32_t>; // instantiate new object (some people prefer smart pointers, which may handle ownership stuff like deletion for you, with cost of overhead)
// return reinterpret_cast<Container<int32_t>*>(value); // alternatively just cast/convert type
break;
}
...
}
}
Another implementation might be a mapping table instead of switch (slow)
using std::unordered_map, depending on the expected amount of types / likelyhood of types in order, etc.
For usage you might either use the C++ virtual feature, use CRTP, or implement functionality directly in the template class - matter of favor and use case.
The above approach allows casting and instatiating.
Depending on use case, duck typing might be an enhancement.
Unfortunately C++ does not (yet?) provide us type reflection at runtime.
Memory management consideration
Instead of dealing with dynamic memory management using raw pointers (as in my example above) one might prefer the use of smart pointers (What is a smart pointer and when should I use one?).
TLDR: smart pointers manage ownership and sharing behavior for you. They delete dynamically created memory for you without the need to care about.
Your example using smart pointers would look like this
std::shared_ptr<Container_base> convert(void* value, DataType data_type) {
switch (data_type) {
case INT32: {
return std::make_shared<Container<int32_t>>();
break;
}
...
}
}

Storing multiple types and returning single type on request

I need to create a class that stores multiple User defined types. It should return one of them, on demand. Is there a way to implement one function to return all the types?
Please note: I cannot use Boost libraries. I need to implement in Visual Studio
class One {};
class Two {};
class Three {};
enum Type
{
OneType,
TwoType,
ThreeType
};
class GenericType
{
template <typename T> // --- How to implement this function
T getValue(Type type)
{
switch(type)
{
case One: return oneType; // Error
case Two: return twoType;
case Three: return threeType;
}
}
shared_ptr<OneType> oneType;
shared_ptr<TwoType> twoType;
shared_ptr<ThreeType> threeType;
Type m_type;
};
In C++11 you have an std::tuple class that does the job. You can retrieve needed element with std::get, like this:
// Create a tuple
std::tuple<std::shared_ptr<OneType>, std::shared_ptr<TwoType>> tuple{null, null};
// Get element
std::get<std::shared_ptr<OneType>>(tuple)
This declaration,
template <typename T> // --- How to implement this function
T getValue(Type type)
… where Type is an enum, makes the run time choice of argument determine the compile time choice of function result type, or alternatively requires the run time selection of argument value to be compatible with the compile time choice of type.
The former is backward in time, so it's not on, and the latter is just silly.
If an ordinary function template is OK for you, then the solution is simple: specialize it for each relevant type.
If you need to have run time selection, then instead use a common result wrapper type. For value semantics it can be a class with union members, i.e. a discriminated union. For reference semantics it can be a pointer to a common base class of the possible result types.

variable return type in c++ class

i have a class with the following structure:
class myClass
{
private:
int type;
classOne objectOne;
classTwo objectTwo;
public:
myClass(classOne object)
{
this->objectOne = object;
this->type = 0;
}
myClass(classTwo object)
{
this->objectTwo = object;
this->type = 1;
}
}
i now want a method returning an object of type classOne if type is 0 and of type classTwo if type is 1. I do not want two methods to achieve this. the classes have different structures.
Is this even possible? Any suggestions are appreciated :)
You can use Boost.Variant to do this. A variant can be constructed directly from any value convertible to one of its bounded types. Similarly, a variant can be assigned any value convertible to one of its bounded types. Heres how you could use it in your class:
class myClass
{
private:
boost::variant<classOne, classTwo> obj;
public:
myClass(classOne object) : obj(object)
{
}
myClass(classTwo object) : obj(object)
{
}
};
It also provides a very convenient boost::get to retrieve the value from the variant.
You can use that to supply code for each bounded type you have(ie classOne and classTwo). Here is an example:
if (classOne * x = boost::get<classOne>(&obj))
{
//Code for classOne
}
else if (classTwo * x = boost::get<classTwo>(&obj)
{
//Code for classTwo
}
However, such code is quite brittle, and without careful attention will likely lead to the introduction of subtle logical errors detectable only at runtime. Thus, real-world use of variant typically demands an access mechanism more robust than get. For this reason, variant supports compile-time checked visitation via apply_visitor. Visitation requires that the programmer explicitly handle (or ignore) each bounded type. Failure to do so results in a compile-time error.
Visitation of a variant requires a visitor object. Like this:
class object_visitor
: public boost::static_visitor<>
{
public:
void operator()(classOne & x) const
{
//Code for classOne
}
void operator()(classTwo & x) const
{
//Code for classTwo
}
};
With the implementation of the above visitor, we can then apply it to obj, as seen in the following:
boost::apply_visitor( object_visitor(), obj );
Unless the two types are related (in which case you can create a function that will return a pointer/reference to the common ancestor) you cannot do that directly in C++.
C++ is a statically typed language, meaning that the type of every expression must be known at compile time, but you are trying to define a function whose return type depends on runtime values.
Depending on the particular problem to solve, there might be different approaches that you could take, including using type erasure (return a boost::any, boost::variant or your own type-erasure).
ClassOne and ClassTwo need to have the same return type then either via inheritance or composition. i.e ClassOne and ClassTwo need to be subclasses of the same super class OR they need to impl the same interface.
I am not sure why you would not use templates for your case.
You can have something like below:
template <class ClassType>
class myClass
{
private:
int type;
ClassType object;
public:
myClass(ClassType object_in)
{
this->object = object_in;
/*
C++ doesn't support reflection so I don't think there
is a robust way of doing the following at runtime.
*/
type = /* Get Type at runtime */;
}
/*
Have another method which return object in a straigtforward way.
*/
};
However, then this become trivial. Any more insight into what your use case is, such that you have to know the type?
Update:
If the ClassType is going to be an Object, you can have a const static int TypeID member for the class, which is set at compile time. You can then use it determine the Type at runtime.
If they're completely different structures, with no common base then an alternative way you can return them from the same function is to use void*.
However that's bad form in C++, usually indicating a design failure - either use two different functions, or use a common base class.
It's apples and oranges. If you put an apple into an recipe that calls for an orange it won't be the same recipe anymore.
The use of type-id is a sign that you need virtual functions for myClass. Even if the other two classes are totally independent, the fact that they are returned by the same function could easily make them inherit a base class. And also you can just return a pair containing class1, class2 and one of them can be null.
The first problem is how you will determine the class of which type has been returned. I think it is possible to return a pointer to structure of this type
struct res {
myClass* c1;
ClassOne* c2;
} ;
The field of the not chosen class is NULL, the other points to the object.

Specifying template arguments from variables in C++

I want to instantiate a template class with data types that are available at runtime in variables. For example, consider this class:
template <typename T, unsigned int U>
class Allocator
{
public:
T * pointer;
Allocator() { pointer = new T[U]; }
~Allocator() { delete [] pointer; }
};
Now I want to use it like this:
int main()
{
string temp = "int";
unsigned int count = 64;
Allocator<temp, count> a;
return 0;
}
Is there any way of doing this?
I am facing this problem in the context of serializing derived classes with base pointers. I use RTTI to identify the real type of derived class, but the information of the real type is stored in a string. My problem is to be able to dynamic_cast to the type (available as a string at runtime) from the base pointer. Please help.
You can't. Data types must be known at compile time. Maybe using Boost or unions may solve the problem in a non-pretty way.
Good luck!
The absence of a reflection mechanism in C++ makes practically impossible the "dynamic creation" based on data with a direct language support.
The only way is to use a "switch", or any equivalent declarative mechanism, like a factory class owning a dispatch map that associate the strings declaring the type to creation function calls.

How to get around inability to overload on return type in C++

I have function which can create a number of different templated types; an simple example of the problem would be:
EncodedMsg<?>* encode(const Msg& msg)
{
if(msg.qty < 100)
return new EncodedMsg<short>(...);
else if(msg.qty < 100000)
return new EncodedMsg<int>(...);
else
return new EncodedMsg<long>(...);
}
The issue I have is that:
The decision as to what to template on is decided inside the function
I can't overload on return type
I don't want to return a base class type of EncodedMsg as I'll then have to decode what type of message it is later on
Can anyone think of a way around this?
You are attempting to use templates in a dynamic fashion, which isn't possible. The template's type must be known at compile time, so you can't differentiate based on a series of conditionals.
To change type at runtime, you'll need polymorphism from classes and inheritance.
Basically, if the test variable msg.qty is not a compile-time constant, this will be impossible. You have to understand that templates can be used to achieve static polymorphism while OOP (inheritance) can be used to achieve dynamic polymorphism. In other words, templates are resolved at compile-time while virtual function calls are resolved at run-time. You can use both at the same time, but you cannot use them for the same purpose (i.e. they are complementary programming paradigms that each has its own application contexts).
If you could, however, get msg.qty to be a compile-time constant of the type Msg (i.e. Msg::qty, as an enum or static const), then you can use the boost::enable_if library. As so:
template <class Msg>
typename boost::enable_if<Msg::qty < 100, EncodedMsg<short> >::type*
encode(const Msg& msg) { return new EncodedMsd<short>(...); };
template <class Msg>
typename boost::enable_if<((Msg::qty >= 100) && (Msg::qty < 100000)), EncodedMsg<short> >::type*
encode(const Msg& msg) { return new EncodedMsd<int>(...); };
template <class Msg>
typename boost::enable_if<Msg::qty >= 100000, EncodedMsg<short> >::type*
encode(const Msg& msg) { return new EncodedMsd<long>(...); };
But in the case that you can determine, for a certain class Msg, what template instantiation to use for the EncodedMsg, then it is a lot easier to define it as a nested typedef in the class Msg, and define your encode function as follows:
template <class Msg>
Msg::encoded_type* encode(const Msg& msg) { return new Msg::encoded_type(...); };
You could also use a type trait (like message_trait or something like that) to define the nested typedef, if you have message classes that are not modifiable.
But, if the msg.qty can only be a run-time value, then there is no choice but to use dynamic polymorphism (i.e. return a pointer to a base class or interface). Or, you can also use a boost::variant. In this case, you can do this:
boost::variant< EncodedMsg<short>,
EncodedMsg<int>,
EncodedMsg<long> >* encode(const Msg& msg)
{
typedef boost::variant< EncodedMsg<short>,
EncodedMsg<int>,
EncodedMsg<long> > result_type;
if(msg.qty < 100)
return new result_type( EncodedMsg<short>(...) );
else if(msg.qty < 100000)
return new result_type( EncodedMsg<int>(...) );
else
return new result_type( EncodedMsg<long>(...) );
};
The above has some obvious problems (like the fact that the result type will be as big as the biggest of the template instantiations of EncodedMsg, but you could solve that with an additional level of indirection (storing pointers to EncodedMsg objects)). And it is not as nice and efficient as a polymorphic alternative if you can find one.
1) You can't overload a return type of a function, but you can overload types
passed to the function and pass by pointer. However, i think this is not what you want, see 2)
2) Basically one has to use a different design approach to the problem:
By using a virtual interface in your base class your method returns the right
class, and one only calls the proper virtual function. You just return the base class (EncodedMsgBase) which can be a EncodedMsg_whatever as long as it's derived from EncodedMsgBase. You can create a template from a base class if you want.
In more complicated scenarios this boils down to an 'how do i create a factory in c++' problem. People usually work around this by passing a base class implementing the 'virtual constructor idiom'.
Check the c++ faq for more info on that:
http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8
Also keep in mind that by using static typing one can avoid a lot of trouble :)
This approach won't allow you to use EncodedMessage everywhere where you wish to further (because I suspect, for example, EncodedMessage<long> and EncodedMessage<short> should both be passable to some method, which operates on EncodedMessages).
Although what you're asking for can be done with tricks, I would advise you to rethink your architecture.
You may simply stick to EncodedMessage<long> and typedef it as TheOnlyPossibleEncodedMessage if it can be used for all message quantities.