Sign in to follow this  

Weird trick.

This topic is 4840 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

class SomeClass
{
public:
   SomeClass(int lots, int of, int needed, int parameters);
...
};

SomeClass MakeSomeClass(int lots, int of, int needed, int parameters)
{
   SomeClass someClass(lots, of, needed, parameters);
   return someClass;
}




If you don't see what I'm doing, I'm just trying to create a short-lived object without having to use new. Is this an abomination (or is it just too slow)? EDIT: Clarity. [Edited by - thedevdan on September 13, 2004 8:06:00 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
The return statement is bogus. Once executed, the stack frame
is out of scope and the returned object may be garbage bits.

Regards,

Share this post


Link to post
Share on other sites
Quote:
Original post by Chris Hare
...a normal constructor call can be used instead of this in normal situations....


Why didn't I think of that? [embarrass]

Well, at least they're equivelant.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
The return statement is bogus. Once executed, the stack frame
is out of scope and the returned object may be garbage bits.

Regards,


Actualy I was kinda thinking something like that could happen.

/MindWipe

Share this post


Link to post
Share on other sites
Quote:
Original post by MindWipe
Quote:
Original post by Anonymous Poster
The return statement is bogus. Once executed, the stack frame
is out of scope and the returned object may be garbage bits.

Regards,


Actualy I was kinda thinking something like that could happen.

/MindWipe


No, it returns by value, not by reference.

Share this post


Link to post
Share on other sites
Quote:
Original post by Chris Hare
This is a godsend with templated types. Instead of
std::pair<std::vector<std::vector<int> >, std::vector<std::vector<int> > >(a, b);
you wrtie
std::make_pair(a, b);


Thanks. [smile]

But my way requires an extra temporary to be created.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
> No, it returns by value, not by reference.

Ah, so it does. Sorry, not used to seeing class objects
returned by value.

Regards,

Share this post


Link to post
Share on other sites
Well, you can't template a typedef, so that won't work, and your method probably doesn't create a temporary [can be optimised away when inlined], especially when written like
return SomeClass(...);

which is how make_pair is written, like this

template<class _T1, class _T2> inline
pair<_T1, _T2> __cdecl make_pair(const _T1& _X, const _T2& _Y)
{return (pair<_T1, _T2>(_X, _Y)); }.

Share this post


Link to post
Share on other sites
Quote:
Original post by Chris Hare
Well, you can't template a typedef, so that won't work, and your method probably doesn't create a temporary [can be optimised away when inlined], especially when written like
return SomeClass(...);

which is how make_pair is written, like this

template<class _T1, class _T2> inline
pair<_T1, _T2> __cdecl make_pair(const _T1& _X, const _T2& _Y)
{return (pair<_T1, _T2>(_X, _Y)); }.


A couple of things:

1. You can typedef a template, but it has to be the final type. However, it doesn't apply to your case.

2. I just tested it by outputting in the destructors. My way does produce an extra temporaty. [sad]

However, your way (return SomeClass(...)) is superior to both.

Share this post


Link to post
Share on other sites
Quote:
Original post by thedevdan
1. You can typedef a template, but it has to be the final type. However, it doesn't apply to your case.

But he said templating a typedef, in other words you can't do something like
template<typename T> typedef std::pair<T,T>;

Quote:
Original post by thedevdan
2. I just tested it by outputting in the destructors. My way does produce an extra temporaty. [sad]

That's doesn't actually tell you anything. Your forcing it to create the temporary because your destructor has side-effects (printing to the screen). Alternatively, it may be running the destructor twice on the same object, although this could only be done safely in relatively few circumstances (eg. your class only contains built-in types, there's no memory (de)allocation, etc.)

Share this post


Link to post
Share on other sites
Quote:
Original post by thedevdan
1. You can typedef a template, but it has to be the final type.


Would you mind explaining how please? I'm genuinely curious since I've just faced this problem in my current project. The C++ Standard does not allow for template typedefs, however the ::rebind<> hack is one way to get around this (at least within the STL). Since rebind<> is not exactly what I wanted I solved my problem by using template functors and some templated polymorphism as wrappers for typedef template function pointers ... but it was clearly a sub-optimal solution. If you have a better one, I'm definitely interested.

Thanks,

Timkin

Share this post


Link to post
Share on other sites
He simply means you may typedef the full instantiation of a template like
typedef vector<double> vd;
I'm not sure of any methods to do what you want in most non pod/struct cases, e.g.

template <class T> class duplet : public pair<T, T> {};
duplet<int> d;
d.first = 3, d.second = 4;
cout << d.first << ", " << d.second << endl;

Share this post


Link to post
Share on other sites
yes, i think he was just pointing it out more than anything :)

thedevdan's way:

Allocate Class (Stack)
Default Constructor
Allocate & Push Call Frame
Allocate Class (Stack)
Overiden Constructor
~4 Assignments
Default Copy Constructor
Deallocate Frame
Default Copy Constructor


Direct Call to Constructor

Allocate Class (Stack)
Overiden Constructor
~4 Assignments



not an accurate representation, but i think you get it idea.

Also, there is absolutly no point in doing thedevdan's method
as the returned memory isnt even persistent (as it would be
if new was used)

Share this post


Link to post
Share on other sites
Quote:
Original post by Beer Hunter
So where's the trick? Didn't you know that you can return objects by value?


Given the way programming in languages like C and C++ is taught these days, that's entirely possible!!! ;)

Timkin

Share this post


Link to post
Share on other sites
Quote:
Original post by mrbreakit
Wait...

This trick makes the computer do a lot more work than it has to. A shortcut to your trick would be to call the constructor directly.

SomeClass s = SomeClass(...);


Actually, it is probable that the function would be inlined and that calling it or colling the constructor would generate the same code.

Share this post


Link to post
Share on other sites
Quote:
Original post by Beer Hunter
Quote:
Original post by thedevdan
Weird trick.
So where's the trick? Didn't you know that you can return objects by value?


I didn't know that you can call constuctors directly. [embarrass]

Share this post


Link to post
Share on other sites

This topic is 4840 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this