【问题标题】:Keeps getting the same C++ error不断收到相同的 C++ 错误
【发布时间】:2016-05-17 12:40:26
【问题描述】:

我有一点 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() 部分。有谁知道如何解决这个问题并使我想要的工作?

【问题讨论】:

  • DoSomethingWithIt的函数定义是什么?
  • DoSomethingWithIt 需要一个非常量指针,但您提供的是一个 const 指针。
  • 尝试将it-&gt;c_str() 切换为&amp;((*it)[0]) :)
  • @Joker_vD,最好做一个可以在代码审查中找到和解释的演员表,而不是应用只写代码。
  • 如果您不确定自己在做什么,请不要抛弃const。修复DoSomethingWithIt 以获取const char*

标签: c++


【解决方案1】:

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

  1. 修改DoSomethingWithIt() 以接受LPCTSTR(这是const char*const wchar_t* 的typedef)而不是LPTSTR。如果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 将成为一个常量迭代器,如果DoSomethingWithIt() 实际上可能会修改您传递给它的缓冲区,它将以未定义的行为结束。

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

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

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

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

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

    这可能会导致files 向量的元素发生变化,如果DoSomethingWithIt() 实际上可能会修改您传递给它的缓冲区,这可能会或可能不会被您接受。但是,如果稍后您将更改代码以使 it 成为 const 迭代器,编译器实际上会检测到它,并会报出与现在报错完全相同的错误,这将允许您重新考虑代码也许使用下一个 sn-p。

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

    如果您想使用此解决方案,但还要保留 DoSomethingWithIt() 对您的 files 中的缓冲区所做的更改(前提是它没有溢出缓冲区并保持为空终止!),您将拥有在DoSomethingWithIt() 调用之后添加这样的内容:

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

    .

【讨论】:

    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多