Whenever I try to compile my code I get an invalid use of auto. Coming from a Java background, I am not sure if I quite understand C++ templates. It seems like the compiler can infer the type. I am limited to C++11.
The error occurs in the GeneralRenderer.
Animal classes
class Animal {};
class Dog : public Animal {};
class Cat : public Animal {};
enum AnimalType {
Dog,
Cat
};
Render Classes
template<class T>
class AnimalRenderer {
virtual void draw(T entity) = 0;
};
class DogRenderer : public AnimalRenderer<Dog> {};
class CatRenderer : public AnimalRenderer<Cat> {};
Logic
class GeneralRenderer {
public:
void draw(
std::map<AnimalType, std::vector<Animal>> animalMap) {
for (auto entry: animalMap) {
AnimalRenderer<auto> renderer; // <--- Causes the error
switch (entry.first) {
case Dog:
renderer = DogRenderer();
break;
case Cat:
renderer = CatRenderer();
break;
}
for (auto animal: entry.second) {
renderer.draw(entry);
}
}
};
};
Informally speaking, auto can be used to declare and initialise a type at the same time. Then the compiler can infer the type from the value used to initialise the variable.
But that's not the case here; a statement like
auto n;
will fail similarly.
Note that auto merely stands in for a type that is known at compile time. It's there to make code more readable although its use is occasionally obligatory such as when working with lambda functions. It is not a variant-type construct cf. std::variant say of C++17.
Finally note that a std::map is a very different beast to a java.util.Map. There's no type erasure in C++ so a std::map<A, B> is a fundamentally different type to a std::map<C, D> if A is a different type to C and / or B differs from D. Furthermore, C++ allows you to store value types in maps.
As the other users already say, auto can‘t work without a righthand variable.
I think you should remove the template annotation from AnimalRenderer, then you can use the classes normally.
To get the result you want you effectively need to move the second for-loop inside the cases, where the deduction can be resolved for each case.
You don't want code duplication, so ideally you want a template function you can call to do the second loop. On the latest c++ standards you might also be able to declare a template lambda function.
That said, architecturally, I would suggest adding an interface base class for AnimalRenderer, and then you can declare a simple pointer to that base class, especially as you have already declared draw as virtual.
Related
I have a tricky question about C++(11) template classes and their instantiation with types determined at runtime:
Following scenario:
The user defines the type of a template class using a config file (ROS parameters). This determines only the type of the template class, not the further logic:
Class definition:
template<typename T>
class MyClass {
//[...]
}
Exemplary code:
/* [Read parameter and write result to bool use_int] */
std::unique_ptr<MyClass> myclassptr {nullptr};
if(use_int) {
myclassptr.reset(MyClass<int>);
} else {
myclassptr.reset(MyClass<double>);
}
myclassptr->foobar();
/* [more code making use of myclassptr] */
So this code is (of course) not compiling, because the unique_ptr template must be specified also with the template type. However, then the problem arises that the template type must be the same for all objects assigned using reset.
One ugly solution would be to copy the code myclassptr->foobar(); and the following into each branch of if/else, which I really don't like.
I would like to see a solution similar to this:
/* [Read parameter and write result to bool use_int] */
MyClass<use_int ? int : double> myclass;
myclass.foobar();
What I have read so far is that something like this is also not possible.
Does anybody have a nice solution for this?
The simplest way to do this is:
class IClass{
virtual ~IClass {}
virtual void foobar()=0;
};
template<typename T>
class MyClass:public IClass {
public:
void foobar() override {
// code here
}
};
std::unique_ptr<IClass> myclassptr {};
if(use_int) {
myclassptr.reset(new MyClass<int>());
} else {
myclassptr.reset(new MyClass<double>());
}
myclassptr->foobar();
boost::variant would be another solution, but is usually used for unrelated types. Type erasure could be done, but again that is usually done when you have unrelated types you want to impose a uniform interface on.
In other languages generics look sort of like templates, but are actually an abstract interface with auto-generated typecasting and some typechecking added. C++ templates are function or class compile time factories. Two outputs of such factories are unrelated at runtime by default, and you can add such relations if you want.
Depending on what you want, you can make MyClass a variant type that holds either an int or a double, or you could use type erasure to hide the implementation behind an interface. The Boost.Variant library can help to implement the former.
In C# I can define this:
public interface BaseObject
{
int GetValue();
}
public class Test<T> where T : BaseClass
{
T BaseObject;
}
which means I know that I can alwaysa call BaseObject.GetValue() / BaseObject->GetValue(); because I know that the baseobject has this method.
Is there a similiar way to do this in C++? So that I can define an interface that multiple classes can inherit and a class that can take advantage of this.
Templates, which are even more powerful than C# generics (not to say they are necessarily better, just different).
template<class T>
class foo
{
public:
int whatever()
{
return obj.GetValue();
}
private:
T obj;
};
A separate class is created for each template argument you use. If you provide a template type which would result in an error you will know at compile time.
You're asking about C++ concepts, a way to specify requirements for template parameters. They were proposed during the work on C++11, but proved complicated enough that they weren't done in time. But they've just been delayed, not forgotten.
In the meantime, duck typing remains very powerful, and it will catch when you pass a template parameter that doesn't have the required interface. It just won't report the problem as neatly.
As a workaround, a simple way to check the constraint you showed takes advantage of the fact that pointer conversions are implicit only when upcasting:
public class Test<T> where T : BaseClass
{
static T* enforcement_helper = 0;
static BaseClass* enforce_inheritance_constraint = enforcement_helper;
};
Depending on how new your compiler is, you may need to put those lines inside a special member function (destructor is good, because it's almost always processed).
But you should only check constraints in order to improve error messages (by causing the failure in a clearly commented section of code). C++ templates are duck typed, and they will work with any template parameters that provide the required operations. No formal "interface" is required.
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.
I have a template class that get two template arguments.
template <class T,class A>
class Z{...};
Say I have four types of T, and same amount for A. So, there are 16 options!
If I want to choose one of them at runtime, I need to write a huge and disgusting case.
I know that C++ doesn't support runtime templates.
Is there another way to do it?
A way to achieve something kind of similar is to add dependencies to class Z and provide these at runtime -- which is known as the Strategy pattern.
Of course this means that class Z is no longer templated with all that this entails. But there's really no way to have your pie and eat it too: templates are a compile-time construct, while you are asking about ways to configure something at runtime. You cannot configure a type at runtime, only an object.
No, there really isn't. It's inherent in the nature of templates that this is completely and totally impossible.
I'm not saying that this is a good solution but I've seen it implemented in the past: you could keep the code for your templated class around in a resource file and compile it at runtime into a pluggable module!
By the way, I would suggest to refactor the problem so that instead of instantiating MN templates you only need M + N; I don't know it this is possible in your problem but it usually is, e.g. if you are translating from a type to another, it's usually possible to introduce an intermediate representation that works for all types. You still need either a case or a form of polymorphism to handle the various type though, but that's kind of inevitable.
Virtual Classes gives you at runtime what templates give you at compile time .. kind of.
Template code when written is not real code, just a template that can be used to generate code. Every time you use it .. it'll usually generate the code right there. eg.
Z<int, std::string> z; // At this point a new class called Z<int, std::string> is defined, then the code to instantiate it at run time is generated.
This might be a useful read: c++ standard practice: virtual interface classes vs. templates
Maybe this is what you're after ? The similar sort of thing using polymorphism and virtual classes ..
class Z{
public:
virtual void doSomething();
};
class ZT : public Z {
public:
void doSomething();
};
class ZA : public Z {
public:
void doSomething();
};
...
void useClasses(Z* ptr) {
ZT* ztPtr = dynamic_cast<ZT*>(ptr); // Runtime conversion
if (ztPtr) {
// do specific stuff for this type
} else {
ptr->doSomething(); // generic behaviour that'll call whichever class ptr actually is
}
}
This may or may not fit your needs, but a simple common interface sounds like what you want:
class Z_interface{ //abstract interface
public:
virtual ~Z_interface() {} //virtual destructor
virtual void func()=0; //virtual member
};
template <class T,class A>
class Z : public Z_interface { //implimentation
public:
virtual ~Z_interface() {}
virtual void func() {}
};
int main() {
std::unique_ptr<Z_interface> ptr;
switch(stuff) { //make the correct type
case 0: ptr = std::unique_ptr<Z_interface>(new Z<int, char>()); break;
case 1: ptr = std::unique_ptr<Z_interface>(new Z<int, short>()); break;
case 2: ptr = std::unique_ptr<Z_interface>(new Z<long, char>()); break;
case 3: ptr = std::unique_ptr<Z_interface>(new Z<long, short>()); break;
};
ptr->func(); //don't care about the type anymore, just the algorithms
}
I want to be able to accept a Message& object which references either a Message1 or Message2 class. I want to be able to create a MessageWithData<Message1> or MessageWithData<Message2> based on the underlying type of the Message& object. For example, see below:
class Message {};
class Message1 : public Message {};
class Message2 : public Message {};
template<typename Message1or2>
class MessageWithData : public Message1or2 { public: int x, y; }
class Handler()
{
public:
void process(const Message& message, int x, int y)
{
// create object messageWithData whose type is
// either a MessageWithData<Message1> or a MessageWithData<Message2>
// based on message's type.. how do I do this?
//
messageWithData.dispatch(...)
}
};
The messageWithData class essentially contains methods inherited from Message which allow it to be dynamically double dispatched back to the handler based on its type. My best solution so far has been to keep the data separate from the message type, and pass it all the way through the dynamic dispatch chain, but I was hoping to come closer to the true idiom of dynamic double dispatch wherein the message type contains the variable data.
(The method I'm more or less following is from http://jogear.net/dynamic-double-dispatch-and-templates)
You're trying to mix runtime and compile-time concepts, namely (runtime-)polymorphism and templates. Sorry, but that is not possible.
Templates operate on types at compile time, also called static types. The static type of message is Message, while its dynamic type might be either Message1 or Message2. Templates don't know anything about dynamic types and they can't operate on them. Go with either runtime polymorphism or compile-time polymorphism, sometimes also called static polymorphism.
The runtime polymorphism approach is the visitor pattern, with double dispatch. Here is an example of compile-time polymorphism, using the CRTP idiom:
template<class TDerived>
class Message{};
class Message1 : public Message<Message1>{};
class Message2 : public Message<Message2>{};
template<class TMessage>
class MessageWithData : public TMessage { public: int x, y; };
class Handler{
public:
template<class TMessage>
void process(Message<TMessage> const& m, int x, int y){
MessageWithData<TMessage> mwd;
mwd.x = 42;
mwd.y = 1337;
}
};
You have
void process(const Message& message, int x, int y)
{
// HERE
messageWithData.dispatch(...)
}
At HERE, you want to create either a MessageWithData<Message1> or a MessageWithData<Message2>, depending on whether message is an instance of Message1 or Message1.
But you cannot do that, because the class template MessageWithData<T> needs to know at compile time what T should be, but that type is not available at that point in the code until runtime by dispatching into message.
As has been mentioned, it is not possible to build your template as is.
I do not see any issue with passing additional parameters, though I would perhaps pack them into a single structure, for ease of manipulation.
Certainly I find it more idiomatic to use a supplementary Data parameter, rather than extending a class hierarchy to shoehorn all this into a pattern.
It is an anti-pattern to try to make a design fit a pattern. The proper way is to adapt the pattern so that it fits the design.
That being said...
There are several alternatives to your solution. Inheritance seems weird, but without the whole design at hand it may be your best bet.
It has been mentioned already that you cannot freely mix compile-time and run-time polymorphisms. I usually use Shims to circumvent the issue:
class Message {};
template <typename T> class MessageShim<T>: public Message {};
class Message1: public MessageShim<Message1> {};
The scheme is simple and allow you to benefit from the best of both worlds:
Message being non-template mean that you can apply traditional OO strategies
MessageShim<T> being template mean that you can apply traditional Generic Programming strategies
Once done, you should be able to get what you want, for better or worse.
As Xeo says, you probably shouldn't do this in this particular case - better design alternatives exist. That said, you can do it with RTTI, but it's generally frowned upon because your process() becomes a centralised maintenance point that needs to be updated as new derived classes are added. That's easily overlooked and prone to run-time errors.
If you must persue this for some reason, then at least generalise the facility so a single function uses RTTI-based runtime type determination to invoke arbitrary behaviour, as in:
#include <iostream>
#include <stdexcept>
struct Base
{
virtual ~Base() { }
template <class Op>
void for_rt_type(Op& op);
};
struct Derived1 : Base
{
void f() { std::cout << "Derived1::f()\n"; }
};
struct Derived2 : Base
{
void f() { std::cout << "Derived2::f()\n"; }
};
template <class Op>
void Base::for_rt_type(Op& op)
{
if (Derived1* p = dynamic_cast<Derived1*>(this))
op(p);
else if (Derived2* p = dynamic_cast<Derived2*>(this))
op(p);
else
throw std::runtime_error("unmatched dynamic type");
}
struct Op
{
template <typename T>
void operator()(T* p)
{
p->f();
}
};
int main()
{
Derived1 d1;
Derived2 d2;
Base* p1 = &d1;
Base* p2 = &d2;
Op op;
p1->for_rt_type(op);
p2->for_rt_type(op);
}
In the code above, you can substitute your own Op and have the same runtime-to-compiletime handover take place. It may or may not help to think of this as a factory method in reverse :-}.
As discussed, for_rt_type has to be updated for each derived type: particularly painful if one team "owns" the base class and other teams write derived classes. As with a lot of slightly hacky things, it's more practical and maintainable in support of private implementation rather than as an API feature of a low-level enterprise library. Wanting to use this is still typically a sign of bad design elsewhere, but not always: occasionally there are algorithms (Ops) that benefit enormously:
compile-time optimisations, dead code removal etc.
derived types only need same semantics, but details can vary
e.g. Derived1::value_type is int, Derived2::value_type is double - allows algorithms for each to be efficient and use appropriate rounding etc.. Similarly for different container types where only a shared API is exercised.
you can use template metaprogramming, SFINAE etc. to customise the behaviours in a derived-type specific way
Personally, I think knowledge of and ability to apply this technique (however rarely) is an important part of mastering polymorphism.