将空字符串作为参数传递给函数

Tec*_*ndz 0 c++

在不创建变量的情况下将 NULL 字符串传递给函数的正确方法是什么?\n我看到以下代码出现编译错误,并且我不想更改定义。还可能需要对字符串进行更改,因此不想将其标记为常量类型。

\n\n
#include <iostream>\n#include <string>\n\nusing namespace std;\nvoid\nmyfunc(int i,  string &my) {\n   if (my.empty()) {\n      cout << "Empty" << endl;\n   } else {\n      cout << "String is " << my <<endl;\n   }\n}\nint main ()\n{\n  std::string str1 ("Test string");\n  myfunc(1, str1);\n  std::string str2 ("");\n  myfunc(2, "");\n  return 0;\n}`\n
Run Code Online (Sandbox Code Playgroud)\n\n

my1.cpp:18: 错误:从 \xe2\x80\x98const char*\xe2\x80\ 类型的临时类型对 \xe2\x80\x98std::string&\xe2\x80\x99 类型的非常量引用进行无效初始化x99\nmy1.cpp:6: 错误:传递 \xe2\x80\x98void myfunc(int, std::string&)\n\xe2\x80\x99 的参数 2 时

\n\n

以下编译但我不想创建局部变量

\n\n
#include <iostream>\n#include <string>\n\nusing namespace std;\nvoid\nmyfunc(int i,  string &my) {\n   if (my.empty()) {\n      cout << "Empty" << endl;\n   } else {\n      cout << "String is " << my <<endl;\n   }\n}\nint main ()\n{\n  std::string str1 ("Test string");\n  myfunc(1, str1);\n  std::string str2 ("");\n  myfunc(2, str2);\n  return 0;\n} \n
Run Code Online (Sandbox Code Playgroud)\n

bol*_*lov 5

这里的解决方案是使用不包含字符串参数的重载。

void myfunc(int i,  string &my) {
      cout << "String is " << my <<endl;
}

void myfunc(int i) {
   cout << "Empty" << endl;
}
Run Code Online (Sandbox Code Playgroud)

int main ()
{
  std::string str1 ("Test string");
  myfunc(1, str1);
  myfunc(2);
}
Run Code Online (Sandbox Code Playgroud)

这是最简单、最清晰的解决方案,可以准确传达您的意图和功能。

您不应该尝试按照自己的方式进行操作,因为如果您想修改参数,则参数应该是“非常量引用”,因此它不能绑定到临时变量。因此你不能向它传递字符串文字。


如果你想明确表示你不传递字符串,你可以创建一个标签 ala nullptr,尽管当上面的变体很清楚并且每个人乍一看都可以理解时,我不建议额外的复杂化。

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;
}
Run Code Online (Sandbox Code Playgroud)

int main ()
{
  std::string str1 ("Test string");
  myfunc(1, str1);
  myfunc(2, no_string_tag);
}
Run Code Online (Sandbox Code Playgroud)

如果您确实想要一个函数,那么语义上正确的版本将有一个可选的引用。

auto foo(int i, std::optional<std::reference_wrapper<std::string>> my)
{
    if (my)
        cout << "String is " << my <<endl;
    else
        cout << "no string" << endl;

}
Run Code Online (Sandbox Code Playgroud)
int main ()
{
  std::string str1 ("Test string");
  myfunc(1, str1);
  myfunc(2, std::nullopt);
}
Run Code Online (Sandbox Code Playgroud)

如果您想保留函数签名并仍然能够临时传递它,那么您就不走运了。C++具有安全功能,因为它不允许将非常量引用绑定到临时引用。此限制的原因是,尝试通过左引用修改临时值很可能是错误,而不是程序员的意图,因为临时值无论如何都会消失。