继续得到相同的C ++错误

时间:2016-05-17 12:40:26

标签: 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);
    }
}

代码。

这是我得到的错误:

  

类型的参数&#34; const wchar_t *&#34;与&#34; LPTSTR&#34;

类型的参数不兼容

错误是代码中的it-&gt; c_str()部分。有谁知道如何解决这个问题并使我想要的工作?

1 个答案:

答案 0 :(得分:1)

我认为DoSomethingWithIt有签名void DoSomethingWithIt(LPTSTR, BOOL)。在这种情况下,您可以执行以下任何操作:

  1. 修改DoSomethingWithIt()以接受LPCTSTRconst char*const wchar_t*的typedef)而不是LPTSTR。如果DoSomethingWithIt()超出您的控制范围,或者实际上需要修改传递给它的缓冲区,这可能是不可行的。

  2. 修改您的主叫网站,通过强制性地使用C风格广告投放wchar_t*修饰符来传递const wchar_t*而不是const

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

    或使用C ++的const_cast运算符,专为此用途而设计:

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

    这会打开一大堆蠕虫,这些蠕虫可能会或可能不会在你的皮肤下爬行并吃掉你的内脏,而你却不会注意它,直到它为时已晚,所以我会反对它。有一天你获得files的方式可能会改变,你的it将成为一个常量迭代器,如果DoSomethingWithIt()实际上可能会修改你传入它的缓冲区,它将以未定义的行为结束

  3. 通过以某种方式向字符串询问指向其第一个字符的wchar_t*指针,修改您的调用网站以传递const wchar_t*而不是wchar_t*。一种方法是:

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

    或者如果你喜欢更浓缩和神秘的风格,像这样:

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

    另一种方法是使用&*str->begin()代替&str[0]&*(it->begin())代替&((*it)[0])。但是,我个人会认为这最后一种方式对我来说太神秘了。

    这可能会导致files向量元素的更改,如果DoSomethingWithIt()实际上可能会修改您传入其中的缓冲区,这可能是您可能接受的,也可能是不可接受的。但是,如果稍后您将以it成为const迭代器的方式更改您的代码,编译器将实际检测到它并将抱怨它现在抱怨的完全相同的错误,这将允许您重新思考代码,也许还可以使用下一个代码段。

  4. 通过将wchar_t*字符串的内容复制到const wchar_t* s的数组(足够长),修改您的调用网站以传递*it而不是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没有义务将其数据存储在连续的块中。但是,由于这样的实现几乎是闻所未闻的,并且C ++ 11要求std::wstring将其数据存储在一个连续的块中,因此这不是一个大问题。

    如果您想使用此解决方案,还要保留DoSomethingWithIt()files中缓冲区所做的更改(前提是它没有溢出缓冲区并保持空终止!),你必须在DoSomethingWithIt()电话后添加类似的内容:

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