Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Passing a Temporary to a Constructor

Posted on 2008-10-01
16
Medium Priority
?
344 Views
Last Modified: 2010-04-01
It seems to be impossible to pass a temporary object to a constructor, because the compiler misinterprets the statement as a function declaration.

For example:

class foo
{ };

class Test
{
      public:

      Test(const foo& f) { }
      void dosomething() { }
};

int main()
{
      Test t(foo());
      t.dosomething(); // <--- error
}

In the above example code, the compiler reports an error when I call t.dosomething, because it interprets Test t(foo()) to be a declaration of a function t, which returns type Test.  However, the code works properly if I pass the constructor a non-temporary instance of foo.

Firstly, why is it even legal to put a function declaration inside another function?  Under what circumstances could that ever be useful?  Secondly, is it at all possible to pass a temporary to a class constructor?
0
Comment
Question by:chsalvia
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 3
  • +3
16 Comments
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 22616618
try this way:

int main()
{
      foo f();
      Test t(f);
      t.dosomething(); // <--- error
}
0
 
LVL 6

Expert Comment

by:RishadanPort
ID: 22616629
you can do this instead which will work:

Test t = Test(foo());


Functions can have inner functions, that is why it is sometimes useful to place prototypes inside a function.
0
 

Author Comment

by:chsalvia
ID: 22617175
>>Functions can have inner functions, that is why it is sometimes useful to place prototypes inside a function.

I'm not sure what you mean here.  It sounds like you're talking about closures, which are not supported by C++.

What do you mean by inner function?
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 6

Expert Comment

by:RishadanPort
ID: 22617801
My Mistake. I thought you could have nested functions in C++, when in fact you can't.

http://www.velocityreviews.com/forums/t277810-nested-functions-in-c.html
0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 500 total points
ID: 22618419
>> Firstly, why is it even legal to put a function declaration inside another function?

Because it gives the programmer more freedom - he can add the function declaration in the local scope, so that it'll only be visible in that scope ... Other scopes can have their own declarations, even with the same name.


>> Secondly, is it at all possible to pass a temporary to a class constructor?

Sure, you just have to do it differently, like shown by others.


>> because the compiler misinterprets the statement as a function declaration.

It doesn't misinterpret it. The standard is very clear about this. If something can be interpreted as both a declaration and a definition, the ambiguity will be resolved in favor of the declaration.
0
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 22618437
there doesn't seem to be a problem with this code. check my snippet below. compiled and linked fine for me. which compiler are you using?

btw i dont think the compiler is dumb to think that it is a function declaration. It has info that Test is a class and you are calling the constructor with an object reference.
The lifetime of the foo object is controlled by the lifetime of object t. So there shouldn't be a problem as long as t is in scope.

What do you mean by a temporary and non temporary instance of foo? can you elaborate
there can be no case where an object needs to be created with no data members especially when you are passing another object to the constructor. your constructor does not seem meaningful.
class A
{
 
};
 
class B
{
public:
	B(const A& foo){}
	void dosum() {}
 
};
 
main()
{
	B obj(A());
	obj.dosum();
}

Open in new window

0
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 22618455
also check this which also works fine
#include <iostream.h>
 
class A
{
public:
	int as;
};
 
class B
{
	int y;
public:
	B(A& foo)
	{
     y=foo.as = 100;
	}
	void dosum() {
	 cout<<y;
	}
 
};
 
main()
{
	B obj(A());
	obj.dosum();
}

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22618504
>> compiled and linked fine for me. which compiler are you using?

My question to you would be : what compiler are YOU using. It's clearly not following the standard. Your compiler should report that obj does not have a class type, and thus the line obj.dosum() is invalid.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22618514
trinitrotoluene, you seem to be using an antiquated compiler ;) <iostream.h> has been deprecated, and should not be used any more.
0
 

Author Comment

by:chsalvia
ID: 22618548
Infinity08,

>>Because it gives the programmer more freedom - he can add the function declaration in the local scope, so that >>it'll only be visible in that scope ... Other scopes can have their own declarations, even with the same name.

I'm not sure I understand this.  How is it at all useful to declare a function inside another function?  It doesn't seem to limit the scope of the function, or really do anything at all.  For example:

int foo()
{
      int bar(); // declare bar
      bar(); // call bar
}

int bar()
{
      cout << "Hello World!" << endl;
}

int main()
{
      foo();
      bar();
}

This code prints out "Hello World" twice.  Main has access to bar(), and so does foo(), even though bar() is declared in the scope of foo().  You can't actually *define* bar in foo, as if it were a closure or something, so what's the point of declaring bar in foo?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22618616
>>  It doesn't seem to limit the scope of the function, or really do anything at all.

No, it doesn't limit the scope of the function - it limits the scope of the function declaration. They are two different concepts (definition vs. declaration).


Consider the following code for example :
#include <iostream>
 
void test() {
  int fun();                // a local function declaration for the 'fun' function
  int value = fun() + 3;    // call the 'fun' function
  std::cout << value << std::endl;
}
 
void test2() {
  char *fun = "fun";        // a local C string named 'fun' - this works because of scope
  std::cout << fun << std::endl;
}
 
int fun() {                 // the 'fun' function definition
  return 5;
}
 
int main(void) {
  test();
  test2();
  return 0;
}

Open in new window

0
 

Author Comment

by:chsalvia
ID: 22619633
I see.  Still, C++ scoping rules would permit the code to compile anyway, even without the localized function definition.  If there is a global function fun(), and then a local scoped variable called fun, the local variable name will take precedence within its scope.  For example, the following code compiles fine:


int fun() {                 // the 'fun' function definition
  return 5;
}
 
void test() {
  int value = fun() + 3;    // call the 'fun' function
  std::cout << value << std::endl;
}
 
void test2() {
  char *fun = "fun";        // a local C string named 'fun' - this works because of scope
  std::cout << fun << std::endl;
}
 
int main(void) {
  test();
  test2();
  return 0;
}

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22619676
Yes, but this was just a simple example. What if you're dealing with multiple files, and multiple 'fun' functions ?

Either way, it doesn't really matter, since a function declaration is a simple declaration, just like a variable declaration. Having it in a local scope is nothing special. A local function declaration is no more special than a local variable declaration. It's all about scope and locality.

You don't have to use local function declarations if you don't want to :)
0
 
LVL 2

Assisted Solution

by:Wouter_
Wouter_ earned 500 total points
ID: 22622467
Scott Meyers calls this "C++'s most vexing parse". Iirc the standard says that if there is ambiguity, prefer to interpret it as a function declaration. I don't remember why anymore.

To pass a temporary in the code you posted you can do this

Test t( (foo()) );
t.dosomething(); // <--- no error

This does not get any prize for elegance but at least there are no extra named variables and I think potentially there are less copies made.
0
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 22642129
infinity08 : I was using Visual Studio 6 and it built fine.

Do you have any good web link on this topic so that I can become more knowledgeable on it.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22642157
>> infinity08 : I was using Visual Studio 6 and it built fine.

That means that Visual Studio 6 is not following the standard :)


>> Do you have any good web link on this topic so that I can become more knowledgeable on it.

Read the C++ standard (ISO-IEC 14882:2003) ;)
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

670 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question