How do I Create and Pass string to function by reference - c++

I am having a constructor like this:
class class_foo{
std::string s_;
class_foo(std::string& s) : s_(s){};
}
I know I can do:
std::string s = "test";
cf = class_foo(s);
Is there a way to do:
cf = class_foo("test");
But is says: note: candidate constructor not viable: expects an l-value for 3rd argument
#eerorika was right. I can simply use a const like here:
link

I am having a constructor like this:
void class_foo(std::string& s) : s_(s){};
A constructor cannot have a return type (even void).
Is there a way to do:
cf = class_foo("test");
Not if you want to keep the argument as non-const reference. It is however unclear why you want it to be non-const reference. Perhaps it doesn't need to be a non-const reference? If you don't intend to modify the argument, then you should use a reference to const. Then your suggested construction would work.

Related

c++11 - initialize std::string from char* directly with {} constructor

I have a function which accepts a std::string&:
void f(std::string& s) { ... }
I have a const char* which should be the input parameter for that function. This works:
const char* s1 = "test";
std::string s2{s};
f(s2);
This doesn't:
const char* s1 = "test";
f({s1});
Why isn't this possible? The funny thing is that CLion IDE is not complaining, but the compiler is:
no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘std::basic_string<char>&’
This has nothing to do with constructing std::string from char const*.
f expects a lvalue to a string, and by creating a temporary instance on the spot, you're providing an rvalue, which cannot be bound to a non-const lvalue reference. f(string{}) is just as invalid.
Your function receives a non const reference and you are passing a temporary object, which requires a copy or a const reference parameter. Two solutions, creating another function to receive the object as a rvalue reference and call the other overload within
void f(string&& s) { f(s); }
to allow temporary objects as parameter, or change your function definition to receive any object but as a constant reference
void f(const std::string& s) { ... }
One option is to change your function to take a string by value, not by reference. Then it will work. In any case, in C++11 sometimes it's preferable to pass by value, not by reference.

Declare a vector in a function call and pass it by reference

I'd like to declare a vector this way:
myFunction(new std::vector<stuff>{});
With the vector passed as a reference:
void myFunction(const std::vector<stuff> &myVec);
You don't need to new the argument (which in any case returns a pointer, not an lvalue). You can simply pass a temporary:
myFunction(std::vector<stuff>{});
A temporary can bind to a const lvalue reference.
If the parameter is optional, you can simply declare the function as
void myFunction(const std::vector<stuff>& myVec = std::vector<stuff>{});
Then, you can call it like myFunction() when the default argument is fine.

passing a const char instead of a std::string as function argument

This is a newbie question but I cannot understand how it works.
Suppose I have the function like the one below
void foo(const std::string& v) {
cout << v << endl;
}
And the call below in my program.
foo("hi!");
Essentially I am passing a const char* to a function argument that is const reference to a string so I have a doubt on this call.
In order to pass an argument by reference, am I right to say that the variable must exist at least for the duration of the call? If it is so, where is created the string that is passed to the function?
I can see that it works : does it happen because the compiler creates a temporary string that is passed to the argument or the function?
does it happen because the compiler creates a temporary string that is passed to the argument or the function?
Yes, and temporaries are allowed to bind to const lvalue references. The temporary string v is alive for the duration of the function call.
Note that this is possible because std::string has a implicit converting constructor with a const char* parameter. It is the same constructor that makes this possible:
std::string s = "foo";

why does boost::assign::ptr_map_insert changes constructor argument calls to const references?

I am confused by the following behavior:
My class "Application" adds in the constructor elements of the type "SplashScreen" (derived from my class "Screen " which is the container type) using ptr_map_insert into a pointer container of the type Screen. Example:
boost::assign::ptr_map_insert<SplashScreen>(screenContainer_)(GameScreens::Splash, curWindow_, curFileSystem_, curInputManager_);
According to the documentation of ptr_map_insert, the last pair of brackets begins with the key and the following arguments are passed to the constructor of the SplashScreen class.
curWindow_ etc. are non-const private members of my class "Application"
I don't know why, but GCC reports an error because the arguments passed to the constructor are const references and the constructor of SplashScreen needs regular references.
SplashScreen(sf::RenderWindow& curWindow, System::FileSystem& curFileSystem, System::InputManager& curInputManager);
The complete error message is below and partially translated by me because it is/was in german.
/usr/include/boost/preprocessor/iteration/detail/local.hpp: In Elementfunktion »boost::assign::ptr_map_inserter<PtrMap, Obj>& boost::assign::ptr_map_inserter<PtrMap, Obj>::operator()(const T&, const T0&, const T1&, const T2&) [with T = Oxid::GameScreens::gameScreenEnum, T0 = sf::RenderWindow, T1 = Oxid::System::FileSystem, T2 = Oxid::System::InputManager, PtrMap = boost::ptr_map<Oxid::GameScreens::gameScreenEnum, Oxid::Screen>, Obj = Oxid::Game::SplashScreen, boost::assign::ptr_map_inserter<PtrMap, Obj> = boost::assign::ptr_map_inserter<boost::ptr_map<Oxid::GameScreens::gameScreenEnum, Oxid::Screen>, Oxid::Game::SplashScreen>]«:
/blabla/main/application.cpp:42:132: instanced(?) from here
/usr/include/boost/preprocessor/iteration/detail/local.hpp:43:1: Error: no matching function for calling »Oxid::Game::SplashScreen::SplashScreen(const sf::RenderWindow&, const Oxid::System::FileSystem&, const Oxid::System::InputManager&)«
/usr/include/boost/preprocessor/iteration/detail/local.hpp:43:1: Anmerkung: candidates are :
../include/splashscreen.h:16:17: Anmerkung: Oxid::Game::SplashScreen::SplashScreen(sf::RenderWindow&, Oxid::System::FileSystem&, Oxid::System::InputManager&)
../include/splashscreen.h:16:17: Anmerkung: no known conversion for argument 1 from »const sf::RenderWindow« to »sf::RenderWindow&«
../include/splashscreen.h:13:15: Anmerkung: Oxid::Game::SplashScreen::SplashScreen(const Oxid::Game::SplashScreen&)
../include/splashscreen.h:13:15: Anmerkung: candidate requires 1 Argument, 3 denoted
The boost sourcecode doesn't indicate that arguments are changed to const or something similar. What did I overlook that this conversion occurs?
Edit: Just viewed the actual boost changelog (I am using 1.48.0) but they don't contain something about this problem.
Regards
As I look at the source it appears that it does take the parameters by const reference, presumably so that in most cases you don't have loss-of-const concerns. I believe that in your case you're going to have to use insert directly on the ptr_map instead of the helper template.

how to initialize function arguments that are classes with default value

I'm working on Linux gcc environment and I need to initilize function arguments that are classes with default values.
When I do that with temporary instance of the class it makes an error like this: "default argument for [function argument] has type [class name].
for example:
void foo(std::wstring& str = std::wstring())
error: default argument for 'std::wstring& str' has type 'std::wstring'
P.S. this code is compiled without any error or warning with VC++.
How can I initilize the default value?
This is supposed to not compile. You are trying to bind an rvalue to a non-const reference. Say std::wstring const & str and it should work.
You could just create a function overload:
void foo() {
std::wstring str;
foo(str);
}
but I really miss the point.
EDIT:
I mean, that function's purpose is almost certainly to modify an input string. If you provide an empty input string that you can't access later, why bother?
You cannot bind non-const references to rvalues. Passing by value would work:
void foo(std::wstring str = std::wstring())
Or passing by reference-to-const:
void foo(const std::wstring& str = std::wstring())