为什么编译器为L“”的隐式类型转换选择bool over string?
最近引入了方法的重载,应用程序开始失败。 最后追踪它,新方法被称为我没有想到它会。为什么编译器为L“”的隐式类型转换选择bool over string?
我们有
setValue(const std::wstring& name, const std::wstring& value);
std::wstring avalue(func());
setValue(L"string", avalue);
std::wstring bvalue(func2() ? L"true", L"false");
setValue(L"bool", bvalue);
setValue(L"empty", L"");
它已更改,这样一个布尔值存储,当我们使用相同的字符串(字符串的内部数据存储)
setValue(const std::wstring& name, const std::wstring& value);
setValue(const std::wstring& name, const bool& value);
std::wstring avalue(func());
setValue(L"string", avalue);
setValue(L"bool", func2());
setValue(L"empty", L""); << --- this FAILS!?!
与L“的问题”是它隐式地投射,以前它很高兴成为一个std :: wstring,但不是它喜欢成为一个布尔。 MSVC编译器不抱怨,或提出警告,所以我担心,即使我“修复”setValue(L“空”,L“”);
setValue(L"empty", std::wstring());
别人可能晚点来,简单地使用setValue(L“empty”,L“”);并且必须再次追踪这个问题。
我们认为明确使用该方法,但它不是此用法的有效关键字。 有没有办法让编译器抱怨这个问题,或以其他方式防止这个问题?否则,我正在考虑改变采用bool的方法的名称,以确保它不能做出错误的猜测。
首先,这个问题的原因:C++标准13.3.3.2
定义了转换序列的顺序。它表示用户定义的转换序列比标准转换序列更差。你的情况发生的是字符串文字经历了一个布尔转换(定义在4.12
这是一个标准转换)。它不使用用户定义的转换为std::wstring
,如果其他过载需要转换。
我建议只更改其中一个重载的名称,或者直接添加接受字符串文字的重载(使用参数类型wchar_t const*
)。
感谢链接到标准和布尔的包装也是一个有用的提示。 – 2008-11-28 00:10:08
当时我引用了错误的标准文本,并认为我的答案无疑是复杂的。我认为,为`wchar_t const *`添加一个oveload会更好。随意给Mark-Ransom打上复选标记,他们基本上都这么说。 – 2009-05-15 14:18:38
您可以使新函数采用除bool之外的其他类型 - 也许只是bool的代理 - 不能从文字字符串转换。但是,我真的只需重命名布尔函数并完成它。
为了简化一点,下面的代码
#include <iostream>
using namespace std;
void f(const string &s)
{ cout << "string version called" << endl; }
void f(const bool &b)
{ cout << "bool version called" << endl; }
int main()
{ f("Hello World"); }
打印 “布尔版本,称为”。你确定你的代码只能使用空字符串吗?
我们目前不使用除空字符串以外的字符串文字。我相信你很正确,这与空白字符串无关。 – 2008-11-25 03:00:23
L“”是指向宽字符串的指针。编译器认为转换为bool优先于转换为std :: wstring。
要解决该问题,引入一个新的setValue:
void setValue(std::wstring const& name, const wchar_t * value);
由于布尔是内置型,从为wchar_t到布尔转化是优选的。我会说最简单的解决方案是添加一个重载,它需要一个wchar_t数组并在其中明确投射:
setValue(const std::wstring& name, const wchar_t s[])
{
setValue(name, wstring(s));
}
添加到我的列表中,其中C++不是最好的语言。 – Qix 2016-10-14 08:34:38