Passing null string to function as an argument
What is the right way of passing NULL string to a function without creating a variable? I see compilation error with following code and I don't want to change the definition. Also may have to make change to string so don't want to mark it a constant type.
#include <iostream>
#include <string>
using namespace std;
void
myfunc(int i, string &my) {
if (my.empty()) {
cout << "Empty" << endl;
} else {
cout << "String is " << my <<endl;
}
}
int main ()
{
std::string str1 ("Test string");
myfunc(1, str1);
std::string str2 ("");
myfunc(2, "");
return 0;
}`
my1.cpp:18: error: invalid initialization of non-const reference of type ‘std::string&’ from a temporary of type ‘const char*’ my1.cpp:6: error: in passing argument 2 of ‘void myfunc(int, std::string&) ’
Following compiles but I dont want to create local variable
#include <iostream>
#include <string>
using namespace std;
void
myfunc(int i, string &my) {
if (my.empty()) {
cout << "Empty" << endl;
} else {
cout << "String is " << my <<endl;
}
}
int main ()
{
std::string str1 ("Test string");
myfunc(1, str1);
std::string str2 ("");
myfunc(2, str2);
return 0;
}
Solution 1:
The solution here is to have an overload that doesn't have the string parameter.
void myfunc(int i, string &my) {
cout << "String is " << my <<endl;
}
void myfunc(int i) {
cout << "Empty" << endl;
}
int main ()
{
std::string str1 ("Test string");
myfunc(1, str1);
myfunc(2);
}
This is the most simple and clear solution that conveys exactly your intent and functionality.
You shouldn't try to do it your way because if you want to modify the argument then the parameter should be "non-const reference" and so it cannot bind to temporaries. Thus you can't pass a string literal to it.
If you want to make it explicit that you don't pass a string, you could create a tag ala nullptr
, although I do not recommend the extra complication when the above variant is clear and understood by everybody at first glance.
struct no_string_tag_t {};
constexpr no_string_tag_t no_string_tag;
void myfunc(int i, string &my) {
cout << "String is " << my <<endl;
}
void myfunc(int i, no_string_tag_t) {
cout << "Empty" << endl;
}
int main ()
{
std::string str1 ("Test string");
myfunc(1, str1);
myfunc(2, no_string_tag);
}
If you really want a single function, then the semantically correct version would have an optional reference.
auto foo(int i, std::optional<std::reference_wrapper<std::string>> my)
{
if (my)
cout << "String is " << my <<endl;
else
cout << "no string" << endl;
}
int main ()
{
std::string str1 ("Test string");
myfunc(1, str1);
myfunc(2, std::nullopt);
}
If you want to keep the function signature and still be able to pass it a temporary, then you are out of luck. C++
has a safety feature in that it does not allow a non-const lreferece to bind to a temporary. The reason for this restriction is that attempting to modify a temporary via a lreference would most likely be bug and not the programmers's intent since the temporary dies out anyway.