44

独学で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:\CPP\TestCP.cpp In function `int setvalue(const char*)': 

 note C:\Dev-Cpp\include\c++\3.4.2\bits\basic_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-Cpp\include\c++\3.4.2\bits\basic_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-Cpp\include\c++\3.4.2\bits\basic_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 を String に割り当てることはできませんか?

4

8 に答える 8

78

null を String に割り当てることはできませんか?

No. std::stringはポインター型ではありません。「ヌル」にすることはできません。値の不在を表すことはできません。これは、null ポインターが表すために使用されるものです。

空の文字列を割り当てる (または) か、クリアする ( ) ことにより、にすることができます。s = ""s = std::string()s.clear()

于 2012-07-23T17:39:35.387 に答える
18

オブジェクトはポインタではないため、C++オブジェクトにNULLまたはを割り当てることはできません。これは、Cスタイルの文字列との重要な違いの1つです。Cスタイルの文字列は、または有効な文字列のいずれかですが、C++は常に何らかの値を格納します。0std::stringNULLstd::string

これを簡単に修正することはできません。番兵の値(たとえば、空の文字列)を予約したい場合は、次のようにすることができます。

const std::string NOT_A_STRING = "";

mValue = NOT_A_STRING;

または、文字列へのポインタを格納して、文字列をnullに設定することもできます。

std::string* mValue = NULL;

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

お役に立てれば!

于 2012-07-23T17:41:12.183 に答える
7

リテラル0は型であり、に割り当てることintはできません。空の文字列を使用または割り当てます。intstd::stringmValue.clear()mValue=""

于 2012-07-23T17:39:08.290 に答える
5

それが良い考えだとは言いませんが(または、ポインターnullptrではないものを使用するセマンティクス)、「 nullable」セマンティクスを提供するクラスを作成するのは比較的簡単です ( 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です。または、このメソッドを使用することもできます。不正なアクセスなどの例外があります。これにより、 Mariaが達成しようとしてhas_value()いたように思われる null 許容セマンティクスが提供されます。

また、C++17 の互換性を待ちたくない場合は、Boost.Optional に関するこの回答を参照してください

于 2016-10-27T08:33:51.460 に答える
4

C スタイルの文字列への null ポインターを処理するために同じ効果を達成する方法は 2 つあります。

三項演算子

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

}

または謙虚な if ステートメント

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

}

どちらの場合も、がnull ポインターでない場合にvalueのみ割り当てられます。他のすべての場合 (つまりnull の場合) には、空の文字列が含まれます。mValuevaluevalue mValue

三項演算子メソッドは、からの値がない場合に代替のデフォルト文字列リテラルを提供するのに役立つ場合がありますvalue

std::string mValue = value ? value : "(NULL)";
于 2013-02-07T12:30:04.003 に答える
0

elseケースは不必要です。オブジェクトを作成するとstring、デフォルトでは空になります。

于 2012-07-23T17:41:37.107 に答える
0

多くの C API は、「デフォルトを使用する」ことを示すために null ポインターを使用します (例: mosquittopp ) 。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 呼び出し自体まですべてをそのままにしておくことができます。

于 2017-04-06T15:48:48.370 に答える