Sign in to follow this  
Tradone

Returning Temporary Value?

Recommended Posts

Tradone    100
Q3: Returning Temporary Value? One last question about pointers, when I have a function that returns a value let's we have this method:
//mystring.h
class MyString{
public:
std::string MyString(string, string);
private:
std::string theString
}

std::string MyString::Concat(std::string para_one, std::string para_two){
theString=para_one;
theString+=para_two;
return theString;
}

//main.cpp
main(){
hello=&MyString("fooz","baz");
}


if I do something like the above I get a warning, address of a temporary value or something. why is it return such an error? and if I want the address of theString, then would I have to change the return type to a reference, as I intended? Q2:Reverse Inline? and another thing...
std::string ReturnAnswer(){
return "abc"
}
int ReturnAnswer(){
return 123;
}
void Calculate(int somenumb){
return somenumb*2
}
int main(){

Calculate(ReturnAnswer());

}


the above is sort of like the opposite of inlines I guess? b/c the compiler chooses which function ( ReturnAnswer() ) to use depending on the return type, which in the above case is an int, but an inline the compiler chooses which function depending on the input parameters not the return value. Q1:Passing References and Const passing references and the compiler complaining that there is no match, and thus forced to make it a const and later on, there is a type mismatch. do u know what i mean? how can I avoid these or am I understanding something wrong? damn, this is so aggrevating, [Edited by - Tradone on April 17, 2006 9:01:28 AM]

Share this post


Link to post
Share on other sites
Antheus    2409

void foo(char *);

const char *x;
foo(x); // I believe this causes the problem

// error C2664: 'foo' : cannot convert parameter 1 from 'const char *' to 'char *'


Or is it something else?


Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
That's because foo() takes a char*. Make it take a const char* and all will be tickity-boo.

Share this post


Link to post
Share on other sites
Tradone    100
sorry about that, I thought this issue was extremely general. b/c I encounter this more than half the time.

Error Messages:

new_shenu.cpp: In function 'int main(int, char**)':
new_shenu.cpp:97: error: no matching function for call to 'Skin::Display(std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >)'
Skin.h:127: note: candidates are: void Skin::Display()
Skin.h:128: note: void Skin::Display(std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >&)
new_shenu.cpp:123: error: no matching function for call to 'Skin::Display(std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >)'
Skin.h:127: note: candidates are: void Skin::Display()
Skin.h:128: note: void Skin::Display(std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >&)
*** Error code 1





//mainData is a Config type.
std::map <std::string, std::string> Config::Get(){
return config;
}
//and config is a map
std::map <std::string, std::string> config;

//new_shenu.cpp:97
skin.Display( mainData.Get() );

//Skin.h:127
void Display();

//Skin.h:128
void Display(std::map<std::string, std::string>& para_skinData);




Share this post


Link to post
Share on other sites
Tradone    100
and this is what I tried next..

//mainData is a Config type.
std::map <std::string, std::string> Config::Get(){
return config;
}
//and config is a map
std::map <std::string, std::string> config;

//new_shenu.cpp:97
skin.Display( mainData.Get() );

//Skin.h:127
void Display();

//Skin.h:128
void Display( [b]const[/b] std::map<std::string, std::string>& para_skinData);






New Errors:

Skin.cpp: In member function 'void Skin::Display(const std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >&)':
Skin.cpp:958: error: no matching function for call to 'Skin::Read(const char [5], const std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >&)'
Skin.cpp:172: note: candidates are: void Skin::Read(std::string)
Skin.cpp:186: note: void Skin::Read(std::string, std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >&)
*** Error code 1







SOOOO ANNOYING!!!

so I follow Skin.cpp:958

void Skin::Display( const std::map<std::string, std::string>& para_skinData){
print::Instance().Header( "success" );
print::Instance().Body( "" );
Read("Head");
[b]Read("Body", para_skinData);[/b] // this is 958
Read("Tail");
print::Instance().Tail( "" );
}





and I search the corresponding method, which was Read.

void Skin::Read( std::string para_loadKey, std::map<std::string, std::string>& para_skinData ){
skinData=NULL;
skinData=¶_skinData;
/*
std::cout << &*skinData;
for( loop=(*skinData).begin(); loop!=(*skinData).end(); loop++ ){
std::cout << loop->first << "=" << loop->second << "\n";
}
*/

if ( TestingMode )
std::cout << "**************Begin Skin::Read(std::string, std::map )****************\n\n";


Read( para_loadKey);

if ( TestingMode )
std::cout << "**************End Skin::Read(std::string, std::map )****************\n\n";

}




Now, many other classes use Read(string, map&), so I can't change Read, but I should change Display. [cry]

Share this post


Link to post
Share on other sites
Tradone    100
Quote:
Original post by Anonymous Poster
That's because foo() takes a char*. Make it take a const char* and all will be tickity-boo.


that's the thing there's so many things that depend on that method that is causing the problem. I need to fix so many things... if I do decide to make that one thing into a const. So I want to know why and when pointers and references when passed through functions are required to change to consts and such...

God.. I'm so tired.
Is it common that everybody has to go through this, or is this just me?

Share this post


Link to post
Share on other sites
Tradone    100
Quote:
Original post by Antheus

void foo(char *);

const char *x;
foo(x); // I believe this causes the problem

// error C2664: 'foo' : cannot convert parameter 1 from 'const char *' to 'char *'


Or is it something else?


I think this is what it is, except my case is a reference.
Actually, that's another thing, I more understand pointers than references. Aren't references supposed to be easier to use and more abstract? idk about that.

If you can just briefly explain to me.... thank you so much.
you just saved me like 3 days of stress and working backwords

Share this post


Link to post
Share on other sites
Antheus    2409
Quote:
Original post by Tradone
that's the thing there's so many things that depend on that method that is causing the problem. I need to fix so many things... if I do decide to make that one thing into a const. So I want to know why and when pointers and references when passed through functions are required to change to consts and such...


Here's a nice overview of const-related cases:
http://www.parashift.com/c++-faq-lite/const-correctness.html

It gives just about all cases of where const can be used, and also what effect it has.



Share this post


Link to post
Share on other sites
Tradone    100
http://www.parashift.com/c++-faq-lite/const-correctness.html

Wow, I've seen that link like a thousand times.
Guess there was a reason why.

Share this post


Link to post
Share on other sites
iMalc    2466
Whilst const-correctness is a very good thing, usually you'd already have experience with it and would write everything correctly from the start. Adding it in later isn't as easy, but it is certainly do-able.

The easiest place to start is with parameters to functions. Change any references passed in into const references if the object is not modified.

Share this post


Link to post
Share on other sites
Tradone    100
and an unrelated topic:

I am not deleting the pData, but I am recording its address pData->Set(std::string), so basically I am using memory leakage to dynamically allocate memory. Is this generally a good use of pointers? Just curious.

for( int i=(int)algorithms::Instance().ToInt( nextDbf.Get("dbf") )-1; i > 0; i-- ){
if( algorithms::Instance().DoesFileExist( "./system/db/" + mainParameter.GetParameterValue("db") + "/data/" + algorithms::Instance().ToString(i) + ".cgi" ) ){
if ( countPage == (int)algorithms::Instance().ToInt(mainParameter.GetParameterValue("page")) ){
std::cout << "./system/db/" << mainParameter.GetParameterValue("db") << "/data/" + algorithms::Instance().ToString(i) << ".cgi";
pData = new Data;
pData->Set( "./system/db/" + mainParameter.GetParameterValue("db") + "/data/" + algorithms::Instance().ToString(i) + ".cgi" );
dataMap[algorithms::Instance().ToString(i)]=pData->Get();
}
if ( countData == (int)algorithms::Instance().ToInt(mainConfig.Get("SnPageLine")) ){
countData=0;
countPage++;
}
countData++;
}
}


Share this post


Link to post
Share on other sites
Tradone    100
One last question about pointers,
when I have a function that returns a value let's we have this method:


//mystring.h
class MyString{
public:
std::string MyString(string, string);
private:
std::string theString
}

std::string MyString::Concat(std::string para_one, std::string para_two){
theString=para_one;
theString+=para_two;
return theString;
}

//main.cpp
main(){
hello=&MyString("fooz","baz");
}



if I do something like the above I get a warning,
address of a temporary value or something.
why is it return such an error?
and if I want the address of theString,
then would I have to change the return type to a reference, as I intended?

and another thing...

std::string ReturnAnswer(){
return "abc"
}
int ReturnAnswer(){
return 123;
}
void Calculate(int somenumb){
return somenumb*2
}
int main(){

Calculate(ReturnAnswer());

}


the above is sort of like the opposite of inlines I guess?
b/c the compiler chooses which function ( ReturnAnswer() ) to use depending on the return type, which in the above case is an int, but an inline the compiler chooses which function depending on the input parameters not the return value.

Share this post


Link to post
Share on other sites
TDragon    679
Quote:
Original post by Tradone
One last question about pointers,
when I have a function that returns a value let's we have this method:

*** Source Snippet Removed ***

if I do something like the above I get a warning,
address of a temporary value or something.
why is it return such an error?
and if I want the address of theString,
then would I have to change the return type to a reference, as I intended?

The returned value of a function is "temporary" to the expression it's used in. In other words, if you were to think of the function call as being replaced by a variable, the variable would cease to exist once that statement was evaluated.

In your particular example (wherein I presume the Mystring declaration in the class to actually be Concat), I can see absolutely no reason to take the address of the return value; std::string hello = mystringobj.Concat("fooz", "baz"); should be plenty.

Quote:

and another thing...
*** Source Snippet Removed ***
the above is sort of like the opposite of inlines I guess?

Does the above even compile?
Quote:

b/c the compiler chooses which function ( ReturnAnswer() ) to use depending on the return type, which in the above case is an int, but an inline the compiler chooses which function depending on the input parameters not the return value.

Technically, the compiler is not allowed to do this; a decent compiler should give an error like "Redeclaration of 'ReturnAnswer()'; previously defined at xxx". You appear to be confusing the term "overloading" with "inline". In function overloading, two different functions are allowed to share the same name as long as their parameters differ; the compiler can always correctly determine which to call by the parameters passed to it, but there are far too many cases where the compiler would not be able to decide based only on return value (nor would one want it to).

Share this post


Link to post
Share on other sites

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