C++中使用条件运算符进行字符串连接的两种情况

mwg9r5ms  于 2023-07-01  发布在  其他
关注(0)|答案(4)|浏览(130)

第一个函数工作得很好:

string createurl(string protocol, string siteName, string domain, bool www = true)
{
    return protocol + "://" + (www ? "www." : "") + siteName + "." + domain;
}

但是第二个会导致编译器错误:

string greeting(string name, string gender)
{
    return "Hello " + ((gender == "Male") ? "Mr" : "Miss") + name;
}

错误:C2110“+’:不能添加两个指针。
这两个函数之间的区别是什么,给予我这个错误,解决方案是什么?

bz4sfanl

bz4sfanl1#

这是因为"Hello " + ((gender == "Male") ? "Mr" : "Miss")操作试图连接两个文字字符串,这是不可能的(文字字符串将衰减为指针,而两个指针没有意义)。
快速的解决方案是将第一个字符串设置为std::string对象:

using namespace std::literals
// ...
return "Hello "s + ((gender == "Male") ? "Mr" : "Miss") + name;

The trailing s in "Hello "s turns it into a std::string object

kqlmhetl

kqlmhetl2#

"Hello "const char[7]类型的文字,因此它试图构造一个const char[7],它衰减为指向第一个元素的指针,并将const char*添加到它。所以才有错误。
要实现你想要的,你可以做以下几点

string greeting(string name, string gender)
{
    return string("Hello ") + ((gender == "Male") ? "Mr" : "Miss") + name;
}

因为there is an overload of operator+ in std::string which accepts const char*

uidvcgyl

uidvcgyl3#

第二个函数的问题是没有一个操作数是std::string,它们都是字符串。+运算符将尝试在两个指针之间执行加法,这是不允许的。
一个非常简单的解决方案是使最左边的操作数为std::string,就像第一个函数一样:

#include <string_view>

// Note: Parameters can be std::string_view.
//       Making them std::string results in unnecessary copying, or creation of strings.
string greeting(string_view name, string_view gender)
{
    return string("Hello ") + (gender == "Male" ? "Mr" : "Miss") + name;
}

或者,使用<format>头文件中的函数(需要C++20):

#include <format>

string greeting(string_view name, string_view gender)
{
    return format("Hello {}. {}", gender == "Male" ? "Mr" : "Mrs", name);
}
hts6caw3

hts6caw34#

+运算符从左到右计算。这意味着如果你有一个超过1个+的“和”,并且没有括号来修改顺序,你需要确保前2个被加数中至少有一个是std::string。(C++不允许使用+添加2个C字符串。
在你的例子中,在最后2个被加数周围添加一个括号可以解决这个问题,因为char const* + std::string会产生std::string

std::string greeting(std::string name, std::string gender)
{
    return "Hello " + (((gender == "Male") ? "Mr" : "Miss") + name);
}

一般来说,你需要保证将内存分配限制在最小值,至少对于经常执行的函数:

std::string greeting(std::string const& name, std::string const& gender)
// passing references to strings can avoid unnecessary copies, if an named string variable is passed
{
    using namespace std::string_view_literals;

    constexpr auto Prefix = "Hello "sv;

    std::string result;

    auto const infix = (gender == "Male") ? "Mr"sv : "Miss"sv;

    result.reserve(Prefix.size() + name.size() + infix.size()); // allocate enough memory to store everything in one go
    result.assign(Prefix).append(infix).append(name); // compose the resulting string in the already allocated memory

    return result;
}

相关问题