C++-将null赋值给std::字符串

C++ - Assigning null to a std::string

本文关键字:std 字符串 赋值 null C++-      更新时间:2023-10-16

我正在自学C++。我有以下代码,但它给出了错误。

#include <iostream>
#include <string>
using namespace std;

int setvalue(const char * value)
{
    string mValue;
    if(value!=0)
    {
       mValue=value;
    }
    else
    {
       mValue=0;
    }
}
int main ()
{
 const char* value = 0;
 setvalue(value);
 cin.get();
 return 0;
}

因此,我想创建一个接受char指针的函数,并将指针传递给它。该函数将指针分配给它的成员变量。我故意传递一个空指针。以下是我得到的错误:

 D:CPPTestCP.cpp In function `int setvalue(const char*)': 
 note C:Dev-Cppincludec++3.4.2bitsbasic_string.h:422 candidates are: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>] 
 note C:Dev-Cppincludec++3.4.2bitsbasic_string.h:422                 std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>] 
 note C:Dev-Cppincludec++3.4.2bitsbasic_string.h:422                 std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>] 

它基本上是在抱怨行:mValue=0;

它为什么抱怨这条线?我不能为字符串分配null?

我不能为字符串分配null?

没有。std::string不是指针类型;它不能被设为"null"。它不能表示没有值,而null指针就是用来表示的。

通过为其分配一个空字符串(s = ""s = std::string())或清除它(s.clear()),可以使为空

不能将NULL0分配给C++std::string对象,因为该对象不是指针。这是与C风格字符串的一个关键区别;C样式字符串可以是NULL或有效字符串,而C++std::string总是存储一些值。

没有简单的解决办法。如果你想保留一个sentinel值(比如,空字符串),那么你可以做一些类似的事情

const std::string NOT_A_STRING = "";
mValue = NOT_A_STRING;

或者,您可以存储一个指向字符串的指针,以便将其设置为null:

std::string* mValue = NULL;
if (value) {
    mValue = new std::string(value);
}

希望这能有所帮助!

文字0的类型为int,不能将int分配给std::string。使用mValue.clear()或指定一个空字符串mValue=""

有两种方法可以考虑,它们在处理C风格字符串的空指针时可以达到相同的效果。

三元算子

void setvalue(const char *value)
{
    std::string mValue = value ? value : "";
}

或者谦逊的if语句

void setvalue(const char *value)
{
    std::string mValue;
    if(value) mValue = value;
}

在这两种情况下,只有当value而不是空指针时,value才被分配给mValue。在所有其他情况下(即,当valuenull时),mValue将包含一个空字符串。

三元运算符方法可能有助于在value:中没有值的情况下提供替代默认字符串文字

std::string mValue = value ? value : "(NULL)";

我不会争辩说这是一个好的想法(或使用nullptr与非指针的事物的语义),但创建一个提供"可为null"语义的类相对简单(请参阅nullable_string)。

然而,这更适合C++17的std::optional:

#include <string>
#include <iostream>
#include <optional>
// optional can be used as the return type of a factory that may fail
std::optional<std::string> create(bool b)
{
    if (b)
        return "Godzilla";
    else
        return {};
}
int main()
{
    std::cout << "create(false) returned "
              << create(false).value_or("empty") << std::endl;
    // optional-returning factory functions are usable as conditions of while and if
    if (auto str = create(true))
    {
        std::cout << "create(true) returned " << *str << std::endl;
    }
}

如示例中所示,std::optional可以转换为bool,或者您可以使用has_value()方法,对坏访问有例外,等等。这为您提供了可为null的语义,这似乎是Maria试图实现的。

如果你不想等待C++17的兼容性,请参阅关于Boost.Optional.的答案

else的情况是不必要的,当您创建string对象时,默认情况下它是空的。

编译器给出错误,因为当为mValue=0编译器赋值时,会为编译时绑定找到赋值运算符=(int),但它不存在于字符串类中。如果我们将下面的语句强制转换为类似mValue=(char)0的char,那么它的编译成功了,因为字符串类包含运算符=(char)方法。

许多C API使用空指针来指示"使用默认值",例如mosquitopp。以下是我使用的模式,基于David Cormack的回答:

    mosqpp::tls_set(
        MqttOptions->CAFile.length() > 0 ? MqttOptions->CAFile.c_str() : NULL,
        MqttOptions->CAPath.length() > 0 ? MqttOptions->CAPath.c_str() : NULL,
        MqttOptions->CertFile.length() > 0 ? MqttOptions->CertFile.c_str() : NULL,
        MqttOptions->KeyFile.length() > 0 ? MqttOptions->KeyFile.c_str() : NULL
    );

它有点麻烦,但允许将所有内容都作为std::string保留到API调用本身。