【问题标题】:cannot convert from const char* to const char *&无法从 const char* 转换为 const char *&
【发布时间】:2018-11-16 21:56:10
【问题描述】:

我正在 VC++ 上编写一个简单的 UTF8 到 WideStr 函数。

MtoW.h

#pragma once
#include <Windows.h>
#include <string>
using namespace std;
wstring UTF8toWide(const char*& in);

MtoW.cpp

#include "MtoW.h"
#include <string>
#include <cassert>
using namespace std;
wstring UTF8toWide(const char*& in) {
    int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, NULL, 0);
    wchar_t* wide_str = new wchar_t[size];
    int result_size = MultiByteToWideChar(CP_UTF8, 0, in, -1, wide_str, size);
    assert(size == result_size);
    return wstring(wide_str);
}

main.cpp

#include <string>
#include <iostream>
#include "MtoW.h"
using namespace std;
int main()
{
    string s = "hi";
    //s.c_str();
    //const char* q = "abc";
    //const char*& c = q;
    wstring q = UTF8toWide(s.c_str()); //error 
}

我收到 cannot convert from const char* to const char *&amp; 错误,为什么?
s.c_str()const char* 类型,我的代码应该可以工作。

【问题讨论】:

  • 看起来UTF8toWide内存泄漏:wchar_t[]在哪里被删除了?
  • @drRobertz :D 我忘记写了。谢谢提醒。

标签: c++ visual-c++ reference pass-by-reference


【解决方案1】:

除了改函数,还要解决new操作符引起的内存泄漏。退出函数前调用delete[] wide_str;,或者使用std::wstring开头:

std::wstring UTF8toWide(const char* in) 
{
    if (!in)
        return std::wstring(L"");
    int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, NULL, 0);
    std::wstring ws(size, L'\0');
    int result_size = MultiByteToWideChar(CP_UTF8, 0, in, -1, &ws[0], size);
    assert(size == result_size);
    return ws;
}

std::string s = u8"ελληνικά";
std::wstring q = UTF8toWide(s.c_str());

或者在 C++11 中使用 #include &lt;codecvt&gt;

wstring q = std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>{ }.from_bytes(s);

【讨论】:

  • 谢谢+1。顺便说一句,文档说 codecvt 自 C++17 以来已被弃用。
【解决方案2】:

std::string::c_str 返回的是一个右值,它不能绑定到对非 const 的左值引用(即const char*&amp;)。

如果in 不会在UTF8toWide() 中修改,您可以将参数类型更改为const char* inconst char* const &amp; in,或者改用命名变量。

string s = "hi";
const char* c = s.c_str();
wstring q = UTF8toWide(c);

【讨论】:

  • 谢谢。但是为什么const CharT* c_str() const;看起来像这样,我的意思是后者const,是不是意味着它是一个类的成员函数?因为 AFAIK,只有成员函数可以在函数名称后有 const
  • @Rick 是的,它是一个成员函数,一个const 成员函数。
  • 好的。但我还是不明白为什么它需要一个const char* const&amp;,后者是const。我知道const char* const&amp;,它是一个constant指针的reference,并且该指针指向一个const char。
  • @Rick 那是因为右值可以绑定到对 const 的引用,而不是对非 const 的引用。例如你可以写const int&amp; ri = 0;,但不能写int&amp; ri = 0;
  • T-T,我可以在 stackoverflow 聊天中占用你几分钟吗?
【解决方案3】:

您不能将非常量左值引用绑定到右值:

UTF8toWide(s.c_str());
           ^^^^^^^^^ this is rvalue

你需要左值:

const char* c = s.c_str();
std::wstring q = UTF8toWide(c); //ok

或者通过删除引用改变UTF8toWide,const char* in就可以了

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多