2016-05-17 18 views
-1

C++の質問が少しあります。私は同じエラーが発生し続けていると私はそれについて何をすべきかわかりません。同じC++エラーが発生し続ける

vector<wstring> files; 

if (ListFiles(L"C:", L"*.txt", files)) { 
    for (vector<wstring>::iterator it = files.begin(); it != files.end(); ++it) { 

     DoSomethingWithIt(it->c_str(), false); 
    } 
} 

コードです。

そして、これは私が取得エラーです: "CONSTはwchar_t *は" 型のパラメータと互換性のないタイプの

引数 "LPTSTR"

エラーがIT-> c_strのためであります()コードの部分。誰もがこれを修正し、私が仕事をしたいものを作る方法を知っていますか?

+0

「DoSomethingWithIt」の機能定義は何ですか? – martijnn2008

+2

'DoSomethingWithIt'は非constポインタを期待していますが、あなたはconstポインタを提供しています。 – dreamlax

+1

'it-> c_str()'を '&((* it)[0]) 'に変更しようとしています:) –

答えて

1

DoSomethingWithItは、void DoSomethingWithIt(LPTSTR, BOOL)という署名があると仮定します。代わりにLPTSTRの(const char*またはconst wchar_t*のtypedefである)LPCTSTRを受け入れるように

  1. 修正DoSomethingWithIt():この場合は、次のいずれかの操作を行うことができます。 DoSomethingWithIt()があなたのコントロールから外れている場合、または実際に渡されたバッファを変更する必要がある場合、これは実行可能ではない可能性があります。

  2. は強制的にCスタイルのキャストを廃止const修飾子をキャストしてwchar_t*の代わりconst wchar_t*を渡すためにあなたの呼び出し元のサイトを変更します。

    DoSomethingWithIt((LPWSTR)it->c_str(), false); 
    

    または特にこの使用のために設計されたC++のconst_castオペレータ、と:

    DoSomethingWithIt(const_cast<wchar_t*>(it->c_str()), false); 
    

    これは、肌の下を這うかもしれないし、肌の内部の臓器を食べるかもしれないし、私はそれに反対しています。ある日、filesの取得方法が変わる可能性があり、itがconstイテレータになり、DoSomethingWithIt()が実際に渡したバッファを変更する可能性があり、未定義の動作で終了します。

  3. の代わりにwchar_t*を渡して、何らかの方法で文字列にwchar_t*の最初の文字へのポインタを尋ねます。

    std::wstring& str = *it; 
    DoSomethingWithIt(&str[0], false); 
    

    かのように、あなたが、より凝縮され、不可解なスタイルを好む場合:

    DoSomethingWithIt(&((*it)[0]), false); 
    

    同じことを行う別の方法ではなく、&str[0]または&*(it->begin())の代わりの&*str->begin()を使用することです一つの方法は、このことだろう&((*it)[0])。しかし、私は個人的には、この最後の方法が私の好みにはあまりにも謎めいていると考えています。

    DoSomethingWithIt()が実際にそれに渡されたバッファを変更して受け入れられるかもしれないし、受け入れられないかもしれない場合、これはfilesベクターの要素の変更につながる可能性があります。しかし、後でitがconstイテレータになるようにコードを変更すると、コンパイラは実際にそれを検出して、今度はまったく同じエラーにぶつかり、コードを再考することができます。次のスニペットを使用してください。

  4. は、(十分な長さの)wchar_tの配列に*it文字列の内容をコピーすることによってwchar_t*代わりにconst wchar_t*を通過するように、呼び出しサイトを変更し、DoSomethingWithItに、その最初の要素へのポインタを渡す:

    std::wstring temp = *it; 
    DoSomethingWithIt(&temp[0], false); 
    

    または

    std::vector<wchar_t> temp(it->begin(), it->end()); 
    temp.push_back(0); // Don't forget the trailing NUL char 
    DoSomethingWithIt(&temp[0], false); 
    

    この方法で、内容filesは変更しないことが保証されていますが、それはよく、または以前のソリューションと比較してわずかなパフォーマンス上のペナルティを招くことはありません。技術的には、C++ 03では、std::wstringはデータを連続したブロックに格納する義務がないため、最後の方法(一時的なベクトル付き)はすべての中で最も信頼できると付け加えなければなりません。しかし、そのような実装はほとんど聞かれておらず、std::wstringはそのデータを連続ブロックに格納することを義務づけているので、これは大きな問題ではない。

    DoSomethingWithIt()files(バッファオーバーフローせずにヌル終了した場合)のバッファに変更したままにしておきたい場合は、何かを追加する必要がありますDoSomethingWithIt()の後にこのようにしてください:

    it->assign(&temp[0], &temp[0] + wcslen(&temp[0])); 
    

関連する問題