2016-10-04 5 views
-4

文字列のベクトルに文字を最初に変換することで文字を挿入しようとしていますが、ケース1は動作しません。誰かがその行動を説明できますか? charをベクターに直接挿入するための回避策はありますか?文字をベクトルのベクトルにプッシュするときに予期しない動作が発生する

// vector of strings 
    vector lt; std::string gt; out; 
    // EDIT - stack overflow is not letting me post "less than" sign so using lt; and gt; instead 

    // a character 
    char ch; 

    // assign some value to ch and push to vector 

    // CASE 1: don't work 
    out.push_back("" + ch); 

    // CASE 2: works 
    string str = ""; 
    out.push_back(str + ch); 

PS - 私はC++ 14

+2

エラーメッセージは、なぜそれが動作しないかを示すはずです。エラーを検索しようとしましたか? Googleにはたくさんの結果があります。 – NathanOliver

+1

実際に動作する実際のコードを投稿します。構文エラーがあります。 –

+0

多分あなたは文字列のリテラルに興味があるでしょう:[例](https://ideone.com/OjOV6Y) –

答えて

1

表すものではありません""用語をstd::stringインスタンスではなく、const char*リテラルなので、を追加するとそれにを使用すると、ポインタ演算を行っており、可能性の線に沿ってコンパイラ警告されます:

警告:配列添字はアレイの境界上にある

std::stringstd::vector<std::string>のようpush_backcharに単純に:

std::vector<std::string> vec; 
char ch = 'a'; 
vec.push_back(std::string()+ch); // construct empty std::string, add ch, push_back 
+0

良い点... ideoneが警告を表示しないことが悪い... –

1

このコードはコンパイルして動作します使用しています:

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

int main() { 
    // vector of strings 

    vector<string> out; 

    // a character 
    char ch; 

    // assign some value to ch and push to vector 

    // Case 0: works because a const char * can be coerced into a string 
    out.push_back(""); 

    // Case 1: Does not work 
    // you can't add a const char * and a char. 
    // Some compilers coerce the char into an int and add that to the pointer 
    // producing undefined behavior (access to un-allocated memory) 
    // out.push_back("" + ' '); 

    // CASE 1a: Works, but I'm 'cheating' by 
    // explicitly constructing a string. 
    out.push_back(string("") + ch); 

    // Case 1b: Works using a different string constructor 
    // This is probably the best approach: 
    out.push_back(string(1, ' ')); 

    // CASE 2: works 
     string str = ""; 
     out.push_back(str + ch); 

    std::cout << "out contains " << out.size() << " entries" << std::endl; 

    return 0; 
} 

結果:

out contains 3 entries 
+0

作品はUBを引き起こす2行を期待しています:) http://coliru.stacked-crooked.com/a/2e682fa6c9de6678 – xinaiz

+0

良い点。私はそれを修正するつもりですが、それはまさに答えではありません。 –

1

コードに問題があります。これにより

/***Check if type is simple template***/ 
template <template<class...> class> 
constexpr bool is_template_type() 
{ return true; } 

template <class> 
constexpr bool is_template_type() 
{ return false; } 

vectorは、変数を作成するための有効な型であれば、あなたは確認することができます:ここで あなたは名前がテンプレートタイプであるかどうかをチェックするのに役立ちます型特性です。だから、:あなたはclass templateの変数を作成することはできませんので

static_assert(!is_template_type<vector>(), 
       "vector is not valid type for creating a variable"); 

は、コンパイルが失敗します。 std::vectorに保存するTYPEを指定する必要があります。あなたの質問のタイトルは言う:文字列

ベクトルは、あなたが代わりにstd::vector<std::string>変数を作成する必要があります。 "" + ch


あなたのコードのもう一つの問題はこれです。 あなたはそれが何と思いますか? ""タイプはchar const[1]であり、chタイプはcharです。 char const[1]は暗黙的にchar const *に変換可能で、ポインタに整数値を追加できるのでコンパイルできます。しかし、これはあなたが望むものではありません!ここで

は、メモリ内のあなたの""です:あなたは""chを追加すると

`\0' ? ? ? ? ? ? ... 
/\ 

、これが結果です:

//ch is 5 for example 
`\0' ? ? ? ? ? ? ... 
      /\ 

だから、あなたには、いくつかの未指定アドレスとstd::stringを作成します。実際には、配列の範囲外にアクセスすることはC++のUndefined Behaviorです。

std::string() + chまたはユーザーW.F.の文字列リテラル構文を使用する必要があります。あなたの質問に彼のコメントで掲示される。不特定の値を使用すると、未定義の動作があまりにもあるので


また、chを初期化することを忘れないでください。

+0

ベクトルは、なぜstackoverflowが文字列部分を表示していないのか分かりませんでした。 –