以boost::lexical_cast
变量作为输入的bool
的输出应为0
或1
值。但是我得到了不同的价值。
这不是正常情况。让我们看一下我编写的示例代码:
#include <string>
#include <boost/lexical_cast.hpp>
int main()
{
bool alfa = true; // Doesn't metter whether alfa is initialized at definition or not
char beta = 71; // An integer value. Different values don't make any differences.
memcpy(&alfa, &beta, sizeof(alfa));
printf("%s\n", boost::lexical_cast<std::string>(alfa).c_str());
}
从此代码中,我得到了"w"
(w的ASCII码为71)作为输出!但是我希望它是一个0
或1
值。
问题仅是bool
变量将投射到的值。给定示例中的bool
变量已被视为true。
引起问题的原因是想象我要转换回转换后的值。那是引发异常的地方,因为例如“ w”字符不能转换为bool
。但是,如果输出为0
或1
,则可以进行重新转换。
std::string converted_value = boost::lexical_cast<std::string>(alfa);
bool reconverted_value = boost::lexical_cast<bool>(converted_value ); // In this line, boost::bad_lexical_cast will be thrown
我想知道输出是否正确,或者这是boost::lexical_cast
中的错误?
当我尝试做同样的事情并将变量转换为int
时,我也遇到了boost::bad_lexical_cast
异常。
我的增强版:1.58
答案 0 :(得分:5)
C ++标准未指定布尔值如何在内存中存储,只是存在两个可能的值:true
和false
。现在,假设在您的计算机上,这些分别存储为1
和0
。允许编译器进行假设,尤其是可以假设这些将是存储在布尔值中的仅有两个值。
因此,当boost::lexical_cast
看到一个布尔值时,它将运行看起来像这样的代码(经过优化)
// Gross oversimplification
std::string lexical_cast(bool value) {
char res = '0' + (int)value;
return std::string(1, res);
}
如果value
是0
或1
,则可以正常工作并完成您想要的操作。但是,您将71
放入其中。因此,我们将'0'
(48
)的ASCII码添加到71
并获得119
,即'w'
的ASCII码。
现在,我不是C ++标准专家,但我猜想,使用memcpy
将非标准值存储到布尔值中是未定义的行为。至少,您的代码不可移植。也许更精通标准的人可以填补我所学方面的空白。
答案 1 :(得分:1)
您违反了规则。您期望C ++会在程序中添加无用的代码来捕获违反规则的人吗?
布尔变量只能为0或1,为false或true。如果您根据规则正确分配了它们,它们就是 。
如果您对它们进行了mcmcpy或reinterpret_cast,则基础实现将显示出来。 bool
是一个存储字节。如果以某种方式将其设置为0或1以外的值,则存在。
我必须仔细检查,但我什至不确定您是否可以保证布尔是一个字节。我认为您可以对此进行指点。但是,如果硬件有某种方法可以创建指向一位的指针,您可能会对C ++所做的事情感到惊讶。