Weird trick.

Started by
22 comments, last by thedevdan 19 years, 7 months ago
> No, it returns by value, not by reference.

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

Regards,
Advertisement
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)); }.
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.
Not giving is not stealing.
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.)
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
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
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;
on a totaly random tipping spree, for that class you
may want to explicitly define a copy constructor and or
a copy operator.

:D
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
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(...);
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 FrameDefault 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)
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
Quote:Original post by thedevdan
Weird trick.
So where's the trick? Didn't you know that you can return objects by value?

This topic is closed to new replies.

Advertisement