使用双引号将字符串初始化为在C++中使用泛型算法是否安全?

Als*_*ton -2 c++ compiler-construction string generics

我正在学习C++ Primer第5版.在页479,它提到了

string sum = accumulate(v.cbegin(), v.cend(), "");因为no + on const char*"" 而不正确

类型v是顺序容器,例如矢量.

我发现使用双引号创建字符串是危险的,特别是对于使用通用算法的情况,因为它需要对象的已定义运算符.

但我无法弄清楚描述的no + on const char*含义是什么?

  1. 它会调用string (const char* s);c-string中定义的构造函数吗?
    我认为这是编译器所做的,因为它解释了用C++中的引号初始化的字符串.

  2. 我们应该用双引号创建一个字符串吗?它会导致overriding on operators失败.

Jer*_*fin 6

那是什么要说的是,你不能为[常量]字符添加指向对方,也不能添加charchar [const] *(当然,从技术上讲,你可以添加一个char到char *,但它不会做你want-什么- 它基本上将它char *视为指向数组的开头,并将其char视为该数组的索引,因此结果将是char *距离原始的一些距离的偏移量,其中距离等于编码你添加的char的值).

std::accumulate从你传递的值的类型作为第三个参数推导它应该用于总和的类型.它尝试使用该类型添加内容,然后当它完成时,它会尝试返回该值(然后,在这种情况下,赋值将尝试转换char const *std::string).最终转换可以正常工作,但中间添加不会.

要使其工作,您需要传递一个实际std::string值作为初始值:

string sum = accumulate(v.cbegin(), v.cend(), string());
Run Code Online (Sandbox Code Playgroud)

这样它将推导出总和类型std::string,因此它将向字符串添加项而不是尝试添加到字符串char const *.如果您的编译器足够新,您可以获得相同的效果:

string sum = accumulate(v.cbegin(), v.cend(), ""s);
Run Code Online (Sandbox Code Playgroud)

C++ 11添加了一个"用户定义的文字"功能,允许这样的后缀调用对象类型的构造函数.C++ 14添加了许多这样的预定义后缀,包括2个使用这样的s后缀 - 这一个(对于字符串文字)创建了一个std::string.另一个(对于整数)创建与std::chrono定时类/函数一起使用的定时值,因此3s意味着"三秒".

  • 只需注意,为了使用`operator'"s` UDL,你必须做更多的工作.即,在使用命名空间std :: literals :: string_literals之前,你必须使用它们将它们带入全局范围. (2认同)