11

最近引入了应用程序开始失败的方法的重载。最后追踪它,新方法在我没想到的地方被调用。

我们有

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"" );

它已更改,以便在存储 bool 值时我们使用相同的字符串(字符串的内部数据存储)

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"empty", L""); 成为

setValue( L"empty", std::wstring() );

其他人可能会稍后再使用 setValue(L"empty", L"" ); 并且不得不再次追查这个问题。

我们曾考虑在方法上使用显式,但它不是此用法的有效关键字。有没有办法让编译器抱怨这个,或者以其他方式阻止这个问题?否则,我正在考虑更改采用 bool 的方法的名称,以确保它不会做出错误的猜测。

4

5 回答 5

12

首先,这个问题的原因:C++ Standard 1定义了转换序列的顺序。它表示用户定义的转换序列比标准转换序列差。在您的情况下发生的是字符串文字经历了布尔转换(定义在. 这是标准转换)。它不使用用户定义的转换,如果它采用另一个重载则需要该转换。[over.ics.rank]/2.14.12std::wstring

我建议简单地更改其中一个重载的名称或添加一个直接接受字符串文字的重载(使用参数 type wchar_t const*)。


1)

在比较隐式转换序列的基本形式时(定义见[over.best.ics]

(2.1) 标准转换序列是比自定义转换序列或省略号转换序列更好的转换序列,
(2.2) 自定义转换序列是比省略号转换序列更好的转换序列。

于 2008-11-25T02:38:26.520 回答
8

L"" 是指向宽字符串的指针。编译器认为转换为 bool 优先于转换为 std::wstring。

为了解决这个问题,引入一个新的 setValue:

void setValue(std::wstring const& name, const wchar_t * value);
于 2008-11-25T03:03:34.440 回答
2

由于 bool 是内置类型,因此首选从 wchar_t 到 bool 的转换。我想说最简单的解决方案是添加一个重载,该重载采用 wchar_t 数组并在那里显式转换:

setValue( const std::wstring& name, const wchar_t s[] )
{
     setValue(name, wstring(s));
}
于 2008-11-25T03:19:28.387 回答
1

为了简化一点,下面的代码

#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-25T02:48:27.357 回答
0

您可以使新函数采用 bool 以外的其他类型——也许只是 bool 的代理——它不能从文字字符串转换。但实际上我只是重命名布尔函数并完成它。

于 2008-11-25T02:37:52.607 回答