Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Passing temporary class instances as arguments in c++

This thread is locked; no one can reply to it. rss feed Print
Passing temporary class instances as arguments in c++
Sevalecan
Member #4,686
June 2004
avatar

So here I am. I have class A and function B.

#SelectExpand
1class HappyClass 2{ 3 public: 4 HappyClass(HappyClass &happy) { 5 // copy stuff here 6 } 7}; 8 9void B(HappyClass argument) 10{ 11 // yatta 12} 13 14int main() 15{ 16 B(Happyclass()); 17}

Can anyone guess what happens? You get an error telling you there is no matching function for HappyClass(HappyClass), valid candidates are HappyClass(HappyClass &).

But you know what, I pass std::strings instantiated right in the parameters all the time, and with several other classes too. I've had this problem before, but I don't ever remember "fixing" it, and apparently it only happens with classes of my own design.

[EDIT]
Nevermind, the constructor needed to take a const reference. :P

TeamTerradactyl: SevalecanDragon: I should shoot you for even CONSIDERING coding like that, but I was ROFLing too hard to stand up. I love it!
My blog about computer nonsense, etc.

anonymous
Member #8025
November 2006

Normal copy constructors don't modify the copied instance. See if this helps:

HappyClass(const HappyClass &happy) 
{  
    // copy stuff here  
}

The Comeau Online error diagnostics is also very informative, showing why const in such cases is important (basic rule: you can't have a non-const reference to a temporary, except in VC++; or in other words, if you don't make reference parameters const where they should be, you can't pass temporary objects to them)

"ComeauTest.c", line 11: error: "HappyClass::HappyClass(HappyClass &)", required
          for copy that was eliminated, is not callable because reference
          parameter cannot be bound to rvalue
  int main() {  B(HappyClass()); }

PS, where do the linebreaks go when copying and pasting code?

Dustin Dettmer
Member #3,935
October 2003
avatar

Here, this should compile (on gcc). *

int main()
{
  B( *({Happyclass t(); &t;}) );
}

* Warning: Don't do what I say.

Tobias Dammers
Member #2,604
August 2002
avatar

Dustin, that is genuinely evil.

Anyway, to clarify; a proper copy constructor goes like this:

class Foo {
  public:
    Foo(const Foo&);
};

anonymous said:

PS, where do the linebreaks go when copying and pasting code?

They should work just fine, provided you use code tags.
Maybe the line end format fscks things up - are you on a mac by any chance?

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Timorg
Member #2,028
March 2002

I cant find the post, but it was discussed recently, its a firefox 3 issue. Open the thread in internet explorer and cut it from there as a work around.

____________________________________________________________________________________________
"c is much better than c++ if you don't need OOP simply because it's smaller and requires less load time." - alethiophile
OMG my sides are hurting from laughing so hard... :D

anonymous
Member #8025
November 2006

There's an error. Should be:

class Happyclass {};

void B(Happyclass& ) {}

int main()
{
  B( *({Happyclass t; &t;}) );
}

But then:

C:\myprograms>g++ untitled1.cpp -pedantic
untitled1.cpp: In function `int main()':
untitled1.cpp:7: error: ISO C++ forbids braced-groups within expressions

Umph, I have Firefox 2... Apparently can't copy with linebreaks if there is the scrollbar.

Dustin Dettmer
Member #3,935
October 2003
avatar

It might be

B( *{(Happyclass t; &t;)} );

I seem to mix it up a lot.

anonymous
Member #8025
November 2006

Nope.

Quote:

7 Untitled1.cpp expected primary-expression before '{' token

Neither way works in standard C++. The first way is allowed by GCC as a compiler extension (and who knows what it means) but you can turn those off with the -pedantic flag (however to me that may also cause errors in some C header, like long long is not a valid type in standard C++ - haven't tried if it is possible to specify C++0x language standard where that would be legal).

Dustin Dettmer
Member #3,935
October 2003
avatar

anonymous said:

(and who knows what it means)

Ah, I never thought you'd ask.

A block written as such: ({ .. }) is a sort of "inline function." This function takes no parameters and returns whatever the last statement is. (It is intended for use inside MACROs but I find it fun and confusing to take it out of that context).

Here is my original code:

B( *({Happyclass t(); &t;}) );

Here is how one might rewrite it using a function:

HappyClass *foo()
{
    Happyclass t;

    return &t;
}

B( *foo() );

bamccaig
Member #7,536
July 2006
avatar

X-G
Member #856
December 2000
avatar

As mentioned, copy-constructors take a const reference, and in general temporaries cannot be passed as non-const references.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Mr. Accident
Member #3,508
May 2003
avatar

HappyClass *foo()
{
    Happyclass t;

    return &t;
}

B( *foo() );

Hmm. Returning the address of a stack-allocated object. That's going to end well. ;)

manny8742
Member #10,415
November 2008

Ok I am a noob what's it going to do, blow up the computer or something?

Mr. Accident
Member #3,508
May 2003
avatar

Returning a pointer to a local? The problem is that the local goes out of scope as soon as the function exits (and if it's a class object, its destructor is called). Trying to use the returned address would result in undefined behavior.

Go to: