[C++] Universal get() function.

Started by
33 comments, last by WindScar 14 years, 2 months ago
Quote:
Yes, but now that I think about it, maybe it would be better if you could just expose a set "name" of classes. For example, a class "guy" with thousands of variables could expose just "name", "age" and "sex", wich would semantically mean "I got a name, i got a age, and i have a sex". That's not private info. So someone would later be able to call: "guy, give me your name" (guy.get(guy::name)) or "guy, give me your age" (guy.get(guy::sex)).

...public:    std::string name;    int age;    sex_t sex;private:    // rest of members...

What's your point? That's exactly what public does.

Quote:
But then I would have to write another function for every new variable I want bullet to be able to be sorted from, wich would be almost a copy from the previous function. In the end I would have thousand of functions that are just the same thing, when I could just call container.sort(speed,asc).

A little bit of magic:
#include <iostream>#include <vector>#include <string>#include <algorithm>#include <cassert>struct obj_t{    int num;    std::string str;    obj_t(int num, const std::string &str): num(num), str(str) {}};template<typename T>struct objPred{    T const obj_t::*var;    objPred(T const obj_t::*var): var(var) {}    bool operator()(const obj_t &a, const obj_t &b) const    {        return a.*var < b.*var;    }};int main(){    std::vector<obj_t> list;    list.push_back(obj_t(42, "abc"));    list.push_back(obj_t(12, "bca"));        // sort by "num" variable    std::sort(list.begin(), list.end(), objPred<int>(&obj_t::num));        assert(list[0].num == 12);    assert(list[1].num == 42);}
Advertisement
Quote:really really thankful if someone post the said way to emulate that generic get() function

Technically:
std::map<std::string, boost::any> clazz;// I think this would be the syntaxint age = clazz["age"].get<int>();


With this approach you don't even need C++ classes, since each map is an instance of aggregate members.
Quote:Original post by WindScar
But until them I would be really really thankful if someone post the said way to emulate that generic get() function because I'm sure if I see that code things will become cleaner. Thanking also keyworks to look for.


Like previously mentioned, that doesn't make sense. If you can do obj.get(obj_t::num), why can't you just do obj.num?

Emulation would work like so:
    template<typename T>    T get(T obj_t::*var)    {        return this->*var;    }    int num = obj.get(&obj_t::num);
While I'm still a bit confused, everything is becoming clearer now, thank you very much. And it is pretty easy to code, why people said otherwise? And the get is actually useless, but the sort isn't. Why people said otherwise? And even though get's useless, it could be useful if this was possible:

class Foo{  public:  T get(T Foo::*var) { if (!locked) return var; }; //BTW I'm still trying to understand how that works.  visible-but-not-accessible:  int a, b, c, d, e, f, g, h, i, j;  bool locked;}

As it would allow you to write the get function only once. Or not?


And about the stuff about storing a class pointer? I've figured out a use for it:
class Board : public Some_Thread_Base_Class{  public:  void logic()  {    artwork->draw();  }  void setArtwork(class* classType)   {    if (!locked)    {      delete artwork;      artwork = new classType(); //classType being replaced by "Artwork" or a derived    }  }  private:  Artwork * artwork;  int flags;}

How can that be coded as C++ doesn't allow this way?
Please point my english mistakes everytime you can.
Quote:Original post by WindScar
How can that be coded as C++ doesn't allow this way?


Google: "factory pattern"

Alternatively, look up polymorphism. However, this is a little bad because the object allocating memory is not in charge of freeing it. (factory might be a little better)

class BaseArt{    virtual ~BaseArt(); //important for base class destructor to be virtual                        //since delete will be called with a base class pointer};class DragonArt : public BaseArt{};class SnakeArt : public BaseArt{};


class MyDeal{public:    MyDeal(): mArt(NULL) {}private:    void setArt( BaseArt *art )    {        if ( mArt )            delete mArt;        mArt = art;    }    BaseArt *mArt;};


void myawesomefunction(){    MyDeal theDeal;    theDeal->setArt( new DragonArt() );}


-me
Anyway, part of the problem here is that it seems like you're either used to doing things in a different language, or you haven't actually learned C++ yet (or both). Different languages express things in different ways. Just because you think something is intuitive doesn't mean that's the only way to do it; there are many logically equivalent ways of expressing the same things (hence lots of different languages that are all functionally equivalent). Certain languages make certain things easier at the expense of making other things hard.

The language is what it is, and it "shouldn't" be one way or another. It just is the way it is, and you need to learn how it works. Once you know how it works you can decide if it's the right tool for you. If it doesn't work to do the things you want to do simply enough, then find another language

-me
Quote:Original post by WindScar
While I'm still a bit confused, everything is becoming clearer now, thank you very much. And it is pretty easy to code, why people said otherwise? And the get is actually useless, but the sort isn't.

Yes I suppose the sort is a little intriguing, though it's a pretty rare case that you would need to sort by so many different variables. And if you're not doing that, then you'd usually just write a few different predicates to help with readability and ease of use.
Quote:Why people said otherwise? And even though get's useless, it could be useful if this was possible:

*** Source Snippet Removed ***
As it would allow you to write the get function only once. Or not?

Yeah but that's essentially what the . operator does - it gets you the member variable [grin]. That's why I don't understand what you're trying to do.
some_variable.num // get num from some_variable

Quote:
And about the stuff about storing a class pointer? I've figured out a use for it:
*** Source Snippet Removed ***
How can that be coded as C++ doesn't allow this way?

Artwork would be the base class, and you'd use polymorphism.
  template <typename T>  void setArtwork()   {    if (!locked)    {      delete artwork;      artwork = new T(); // assuming T is a derived type of Artwork    }  }// usagemyThing.setArtwork<specialKindOfArtwork>();
Can you explain your purpose ?
From where I stand it sounds like you just want to have a special kind of syntax in C++ with private members.
No, actually the problem is that you are creating the class from outside then sending a pointer to it, but if some requeriments must be meet before creating the instance, then one you should check from outside the function everytime before you call it. Just wrong.
Please point my english mistakes everytime you can.
Quote:Original post by WindScar
No, actually the problem is that you are creating the class from outside then sending a pointer to it, but if some requeriments must be meet before creating the instance, then one you should check from outside the function everytime before you call it. Just wrong.
nullsquared's code is exactly what you posted, but is actually valid C++. I don't see the problem with it?

This topic is closed to new replies.

Advertisement