C++ 是否在某处定义了空的std::string?

C++ 是否在某处定义了空的std::string?,c++,string,C++,String,是否在某处定义了空的std::string 我的意思是: // code #3 const std::string EMPTY_STR; int process(const std::string &s = EMPTY_STR); // later I can use: process(); // fine, no object is created... class StringRef { ... StringRef(const std::string& st

是否在某处定义了空的
std::string

我的意思是:

// code #3
const std::string EMPTY_STR;
int process(const std::string &s = EMPTY_STR);
// later I can use:
process(); // fine, no object is created...
class StringRef {
    ...
    StringRef(const std::string& str) : b(str.begin()), end(str.end()) {}
    StringRef(const char* str) : b(str), end(str + strlen(str)) {}
    ...
    private:
    const char* const b;
    const char* const e;
};

void foo(const StringRef str);
我可以做到:

// code #1
int process(const char *s = nullptr);
// later I can use:
process();
但是,如果我这样做:

// code #2
int process(const std::string &s = "");
// later I can use:
process(); // wait, an object is created...
它编译并工作,当我使用该函数时,不需要创建对象

是否有标准方法来执行以下操作:

// code #3
const std::string EMPTY_STR;
int process(const std::string &s = EMPTY_STR);
// later I can use:
process(); // fine, no object is created...
class StringRef {
    ...
    StringRef(const std::string& str) : b(str.begin()), end(str.end()) {}
    StringRef(const char* str) : b(str), end(str + strlen(str)) {}
    ...
    private:
    const char* const b;
    const char* const e;
};

void foo(const StringRef str);
这不是瓶颈,也不是过早的优化

<>我相信C++不是java,所以正确的方法不是创建你不需要的对象。 此外,我认为
code 3
看起来比
code 2
好得多,而且它表明字符串是空的(并且可能不会被使用),而
code 2
则不太清楚为什么字符串是

没有(安全的)方法使引用不引用任何内容。如果你根本不想创建一个对象,你必须使用一个指针

int process(const std::string *s = nullptr);
如果要使用引用,必须在某处有一个对象。为此,可以使用默认构造的(空)字符串作为默认参数

int process(const std::string& s = std::string());

首先,我有点惊讶你需要一件物品。它将是一个const对象,那么它给了你什么,而简单的const char*没有

第二,你的问题有一个通用的解决方案。以下无处不在的代码确实存在问题:

void foo(const std::string& data);
它允许将foo与std::strings和const char*一起使用,并且几乎适合所有人。这对大多数foo()用户来说并不重要,但对于那些真正关注性能(如纳秒)的人来说,从const char*创建临时std::string是一个痛处。为了解决这个问题,发明了StringRef。它在std中不可用,但它存在于包括boost在内的许多库中,并且易于实现。想法如下:

// code #3
const std::string EMPTY_STR;
int process(const std::string &s = EMPTY_STR);
// later I can use:
process(); // fine, no object is created...
class StringRef {
    ...
    StringRef(const std::string& str) : b(str.begin()), end(str.end()) {}
    StringRef(const char* str) : b(str), end(str + strlen(str)) {}
    ...
    private:
    const char* const b;
    const char* const e;
};

void foo(const StringRef str);

如果这是一个实际的性能瓶颈,您总是可以选择提供一个重载,该重载接受零个参数和一个字符串。我不相信有预定义的空字符串,因为不需要。但是如果你真的想要一个,没有人会阻止你在某个地方创建自己的
静态
。@Nick如果你想要速度,就不要。我打赌访问这个静态变量的速度会比现在慢(至少不会快)。值得注意的是,短字符串/零长度字符串优化使得创建这样一个临时变量几乎是免费的(=不涉及堆分配)。我认为您应该去掉所有大写常量的坏习惯。它们不再是预处理器宏了。你可以使用指针,而不必。还有其他的选择,比如boost::optional,我知道boost::optional。我来自C、Java和PHP,并试图最大限度地减少指针的使用……在最近的编译器中,还有std::experimental::optional,它可能会成为C++17<代码>int进程(std::experiorative::optional s=std::experiorative::nullopt),尽管这意味着您总是按值传递。另外,在正确的情况下,不要害怕使用指针。我并不反对
StringRef
,但对于“优化”表示空字符串的对象的创建这一特殊情况,我并不清楚它在小字符串优化方面是否比
std::string
好得多。评估的条件可能更少。@SteveJessop,我把这当作推广StringRef的机会,StringRef没有得到应有的爱(甚至没有进入std)。当然,对于空字符串的创建,它没有任何区别。