[C++] Universal get() function.

Started by
33 comments, last by WindScar 14 years, 2 months ago
Because if it was like SQL, it would be like SQL and not C++.

I think you might be enlighened by doing some research about the basic principles behind the design (*) of C++. It is not quite the kitchen sink it appears at a glance.

You might be interested in C#, which includes certain high level features like "LINQ" which appears similar to SQL, and because it allows refection would make it a lot easier to implement some of the stuff you are talking about. Or a language like Ruby, which again makes it relatively easy to do such things.

* its there somewhere
Advertisement
Quote:Original post by geolycosa
Quote:Original post by WindScar
But why it doesn't? Mysql for example got "sort obj by var ASC" and is great, so I don't se reasons for ommiting that possibility.


Speed. C++ is build for speed. Reflection systems always require some kind of class metadata and have an effect on performance.


Not necessarily. C++'s mantra is "you don't pay for what you don't use", not "speed at all costs". If Windscar's hypothetical feature could be implemented in such a way that programs that didn't use it wouldn't require any overhead then "speed" shouldn't be an issue.

The lack of new uses for existing keywords and symbols would be an impediment however, I don't think the committee even consider ideas that don't redefine keywords we know, love and understand into things were any original semantic meaning is lost.
You could just try a more flexible tool (language).
Innovation not reiterationIf at any point I look as if I know what I'm doing don't worry it was probably an accident.
Now that you know those can't be done the way you want to, this is how they would be in C++:

Quote:
1. Simplify the parameters call when many variables have default values.
EG: Being able to call: bullet(speed=4) instead of bullet(0,0,4), when the middle 2 variables are, for exemple, it's position and their defaults are 0.

bullet(speed=4) means that you know the name of the variable. If you know the name of the variable, then you defeat the purpose of private scoping - which is to encapsulate private fields so that they may change without breaking any user code. As such, simply make the variable a public variable (thus it becomes part of the public interface, which shouldn't change in a good design).
someBullet.speed = 4; // same effect via public variables


Quote:
2. Be able to make a sort function to my container that sorts it's contained objects from one of it's variables, example:

container<bullet> bullets(bullet(0,0,3), bullet(20,1,4), (4,3,1));
bullets.sort(speed,1); //sort by speed asc
bullets.sort(x,0); //sort by x desc


We do this in C++ with predicates:
struct speedPred{    bool operator()(const bullet &a, const bullet &b)    {        return a.speed < b.speed;    }};std::sort(bullets.begin(), bullets.end(), speedPred());// same idea for anything else


Quote:
3. Be able tell a function what object to create. Example:

class sweetiesFabric { blabla };
class chokobunny { blabla };
class goodcake { blabla };
sweeties_fabric_obj.create(chokobunny);
sweeties_fabric_obj.create(goodcake);

This is done via templates.
sweeties_fabric_obj.create<chokobunny>();

Except that it probably won't solve the problem you're looking to solve once you learn about how templates work, but I'll leave that for later.

Quote:
And, also, the get() function proposed won't violate the private as it is supposed to return just a copy of the variables.

It violates private because you know the name of the private variable, which you shouldn't. Private isn't about modification, it's about encapsulation.
Just read something about reflective programming and that seem just a awesome idea, so sad C++ doesn't provide suppor to it.

But reflective goes as far as changing code blocks in runtime. I just want a way to send a class type to a function call and nothing else so it's more natural than having a new version of the function for every new class I create. There should be a way in C++.



@nullsquared
Quote:
Now that you know those can't be done the way you want to, this is how they would be in C++:

Quote:
1. Simplify the parameters call when many variables have default values.
EG: Being able to call: bullet(speed=4) instead of bullet(0,0,4), when the middle 2 variables are, for exemple, it's position and their defaults are 0.

bullet(speed=4) means that you know the name of the variable. If you know the name of the variable, then you defeat the purpose of private scoping - which is to encapsulate private fields so that they may change without breaking any user code. As such, simply make the variable a public variable (thus it becomes part of the public interface, which shouldn't change in a good design).
someBullet.speed = 4; // same effect via public variables



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)).

Quote:
Quote:
2. Be able to make a sort function to my container that sorts it's contained objects from one of it's variables, example:

container<bullet> bullets(bullet(0,0,3), bullet(20,1,4), (4,3,1));
bullets.sort(speed,1); //sort by speed asc
bullets.sort(x,0); //sort by x desc


We do this in C++ with predicates:
struct speedPred{    bool operator()(const bullet &a, const bullet &b)    {        return a.speed < b.speed;    }};std::sort(bullets.begin(), bullets.end(), speedPred());// same idea for anything else


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).


Quote:
Quote:
3. Be able tell a function what object to create. Example:

class sweetiesFabric { blabla };
class chokobunny { blabla };
class goodcake { blabla };
sweeties_fabric_obj.create(chokobunny);
sweeties_fabric_obj.create(goodcake);

This is done via templates.
sweeties_fabric_obj.create<chokobunny>();

Except that it probably won't solve the problem you're looking to solve once you learn about how templates work, but I'll leave that for later.

Of course, stupid from my part - I actually wanted to mean a way to store the object type in a variable and then send it to the fabric. For example:
class goodcake;
class guyWhoWantsCake;
guyWhoWantsCake guy(goodcake);
fabric.createCake(guy.getWantedCake());



So I know it can't be done in C++ but what do you guys think about the concept?

[Edited by - WindScar on February 12, 2010 4:09:48 PM]
Please point my english mistakes everytime you can.
Quote:There should be a way in C++.
Should a minivan be able to go from 0 to 60 in 6 seconds? Should a high-performance sports car be able to comfortably seat a family of five?

Different languages have different characteristics, strengths, and weaknesses, and some are more applicable to certain problem domains than others. Fortunately there's a lot of languages to choose from, so if C++ doesn't offer the features you need, you have a lot of other options.
Quote:I just want a way to send a class type to a function call and nothing else so it's more natural than having a new version of the function for every new class I create.
I'm not sure what you mean by 'send a class type to a function call', but for what it's worth, there are a lot of ways to avoid code duplication in C++ (such as using templates), so I wouldn't assume that the only to solve the problems you're trying to solve is to write a lot of duplicate code.
But that's just one thing I need, it doesn't justify changing the entire language as I'm already used to C++ and everything else is fine.

I think I know how I can express myself better: the same way we can store pointer to functions, I want to store like a pointer to a class so I can know in runtime what class to work on. That's it, basically. If it can't be done, how can it be emulated?
Please point my english mistakes everytime you can.
Have you looked into using templates?

You don't even need templates, you can go with the manual factory option:
class base { virtual ~base(); };class chokobunny : public base { blabla };class goodcake : public base { blabla };class sweetiesFabric {    base *create(const std::string &type)   {       if(type == "chokobunny") {           return new chokobunny();       } else if(type == "goodcake") {           return new goodcake(args);       } else {           /* handle type not found error */       }}// laterbase *base = sweeties_fabric_obj.create("chokobunny");base * base = sweeties_fabric_obj.create("goodcake");

It may not be glamorous, but not all code has to be.
Yes I just covered the reason I don't in my last post. Because it wouldn't allow me to store what type to be used in a variable for later use and because of obvious maintenance issues.

And now that I think about it, a pointer to a class wouldn't be enough also. I'm a bit lost in the concepts, I'll research and think about it then I come back when I'm done. 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.
Please point my english mistakes everytime you can.
C++ isn't expressive enough to write such a generic get function.

This is why game logic is often written in a scripting language like Lua that can be "embedded" inside the main C++ core. Writing such a generic get function in lua is trivial.

TBH if I had to do what you are talking about I would implement my objects as std::map<std::string, variant_type> (variant_type probably boost::variant or boost::any). At the end of the day you will have to accept that every language is limited, and what you are trying to do (in your OP) is impossible in C++. Something like the following is quite doable, and in some ways more flexible than what you were aiming for originally (variables don't need to be compile time constants, they could be generated at runtime or read from a file or quake-style console).
int main(){   object guy;   guy["speed"] = 15;   std::cout << guy.get<int>("speed");   return 0;}

This topic is closed to new replies.

Advertisement