JiiPee <no@notvalid.com>: Mar 07 06:29PM Say we have: class Base {}; class Derived : public Base { public: voit foo() {} }; And I create: Base* a = new Derived(); Now is it possible to create a function which will automatically return a correct type (without doing casts in the function) so I can call it like this: Derived* b = foo2(); I tried this: auto foo2()->decltype(a) { return a; } But it just returns Base type pointer (not the real type). Or is the only way to do this to do a cast (for return value)? I would like to use it like: foo2()->foo(); now I need to do it: dynamic_cast<Derived *>(foo2())->foo(); I need this in my real code.... |
Marcel Mueller <news.5.maazl@spamgourmet.org>: Mar 07 07:37PM +0100 On 07.03.15 19.29, JiiPee wrote: > auto foo2()->decltype(a) { return a; } > But it just returns Base type pointer (not the real type). Well, it works as designed. Decltype returns the *declared* type of an expression. Probably you are looking for typeid. Marcel |
JiiPee <no@notvalid.com>: Mar 07 06:46PM On 07/03/2015 18:37, Marcel Mueller wrote: > expression. > Probably you are looking for typeid. > Marcel oh you mean using typeid to find out which type it is (with if-blocks) and the return casted pointer? That might work, but I was thinking is it doable without if-sections (because there might be 10 different types later on)? |
JiiPee <no@notvalid.com>: Mar 07 07:01PM Here is a full code which illustrates what I would like to have (and its close to my real code as well). In the code (main.cpp) below I have to do it something like this: ((Animal<int>*)farm.getAnimal(0))->speak(2015); ((Animal<string>*)farm.getAnimal(1))->speak("hello"); But I would like to do it like this: farm.getAnimal(0)->speak(2015); farm.getAnimal(1)->speak("hello"); Which is only possible if getAnimal() is able to return the animals real type (dog here). So is it possible to return different type with different function parameter index? The point being that I want to use templates and I also want to have as simple call as possible, rather without no casts. the full code: =============================================== class AnimalBase { public: virtual ~AnimalBase() = 0; }; AnimalBase::~AnimalBase() { std::cout<<"~AnimalBase"; } template <typename T> class Animal : public AnimalBase { public: virtual void speak(T speakMore) {} virtual ~Animal() {std::cout<<"~Animal";} }; template <typename T> class Dog : public Animal<T> { public: T m_whatToSpeak; // about age or its name? void speak(T speakMore); virtual ~Dog() {std::cout<<"~Dog";} }; // Specialized functions to speak according to the type of m_whatToSpeak. // int means that dog is talking about its age and string means that it talks about // its name. template <> void Dog<int>::speak(int speakMore) { std::cout<<"Dogs age is: "<<m_whatToSpeak<<", message: "<<speakMore<<std::endl; } template <> void Dog<std::string>::speak(string speakMore) { std::cout<<"Dogs name is: "<<m_whatToSpeak<<", message: "<<speakMore<<std::endl; } class Farm { public: // AnimalBase* is used in order to dynamically add templated dogs vector<AnimalBase*> m_animals; AnimalBase* getAnimal(int i) { return m_animals[i]; } void addDogs(); ~Farm() { for(auto a : m_animals) delete a; } }; void Farm::addDogs() { // We want the first dog to talk about its age (5) m_animals.push_back(new Dog<int>()); ((Dog<int>*) m_animals[0])->m_whatToSpeak = 5; // We want the first dog to talk about its name (Willy) m_animals.push_back(new Dog<std::string>()); ((Dog<std::string>*) m_animals[1])->m_whatToSpeak = "Willy"; } // Depending on what type of dog I have I have to use different types // for those dogs to be used in class. int main() { Farm farm; farm.addDogs(); ((Animal<int>*)farm.getAnimal(0))->speak(2015); ((Animal<string>*)farm.getAnimal(1))->speak("hello"); return 0; } |
JiiPee <no@notvalid.com>: Mar 07 08:10PM On 07/03/2015 19:31, Stefan Ram wrote: > at compile time or a run time. Then, you can use > templates for compile-time polymorphism; but you > can't use them for run-time polymorphism. yes true, I guess its kind of mix now... am doing both. without templates there is more code and I have to copy a lot of code, so I kind of prefer template approach. But I just dont like that casting :). But I guess I am trying to take best of the both worlds ... |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 07 08:39PM On 07/03/2015 20:10, JiiPee wrote: > templates there is more code and I have to copy a lot of code, so I kind > of prefer template approach. But I just dont like that casting :). > But I guess I am trying to take best of the both worlds ... Have a look at the visitor pattern. /Flibble |
Richard Damon <Richard@Damon-Family.org>: Mar 07 06:17PM -0500 I see two basic ways to solve you problem. One, is to have all version of speak as overloads in the AnimalBase class (as virtuals, so the derived classes can redefine, which means it can't be a template) with run time handling of using a version that isn't supported for this type of animal. This gives your run time binding. Two, is to have different versions of getAnimal for each type of animal, which returns the right type of pointer for that animal. This gives you compile time binding. If might make sense for getAnimal to be a template function, with an explicitly specified type, and you have the cast in the template. This seems to be what you are looking for. The issue is that you can't overload on return type or make the static return type of a function determined at run time. |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Mar 07 07:44PM On Tue, 2015-03-03, Scott Lurndal wrote: > bilsch <king621@comcast.net> writes: ... >> error: range-based ???for??? loops are not allowed in C++98 mode > man pages are your friend: > bash$ man g++ | col -b | grep -i c++11 Yes, but with GCC you really need the info pages. Not my favorite documentation format, but that's where the full compiler documentation is, so you need to have it and be able to navigate it. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
ram@zedat.fu-berlin.de (Stefan Ram): Mar 07 07:31PM >So is it possible to return different type with different function >parameter index? The point being that I want to use templates and I also >want to have as simple call as possible, rather without no casts. First make up your mind whether you want to bind at compile time or a run time. Then, you can use templates for compile-time polymorphism; but you can't use them for run-time polymorphism. |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Mar 07 05:49PM On Thu, 2015-03-05, Paavo Helde wrote: >> look like an optional extra instead of being an essential part of the >> cast. > This just tells that you have not written enough templated C++ code yet. In the sense that if you had, you'd see 'const_cast<LPTSTR>' as the function, and 'text' as the parameter. For me, C-style casts look uglier nowadays. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment