首页 > 解决方案 > `const std::string& s = nullptr` 如何作为可选参数工作

问题描述

据我所知,引用不能为空,但是当我运行这样的代码时:

#include <iostream>
#include <string>

void test(int i, const std::string& s = nullptr) {
  std::cout << i << " " << s << std::endl;
}

int main() {
  test(1, "test");
  test(2);
}

可选参数s可以为null,代码构建完成。更重要的是,程序在test(2)运行时会抛出异常,而不是打印一些随机字符串。

当我更改s为 int 之类的基本类型时,它无法编译,所以我认为魔法仍然存在于 string 类中,但是如何呢?

更重要的是,我如何检查是否s为空?如果我使用if(s==nullptr)or if(s.empty()),则无法编译。

标签: c++referencestdstringinitializernullptr

解决方案


test使用以下构造函数 5 初始化其参数std::basic_string<char>

basic_string( const CharT* s,
              const Allocator& alloc = Allocator() );

因为它需要实现一个临时的 ( std::string) 来绑定到该引用。这是因为引用必须绑定到正确类型的对象,而std::nullptr_t事实并非如此。并且所述构造函数对传递的指针具有非空约束。在没有显式参数的情况下调用test会导致未定义的行为。

明确地说,在格式良好的 C++ 程序中不存在空引用之类的东西。引用必须绑定到有效对象。尝试初始化一个nullptr只会寻求进行转换。

由于 astd::string是具有明确定义的“空”状态的对象,因此固定版本可以简单地传入默认的初始化字符串:

void test(int i, const std::string& s = {}); // Empty string by default.

一旦合同违规被修复,s.empty()应该再次给出有意义的结果。


推荐阅读