题
Boost 1.55,MSVC Express 2012。 与摩托教池的表达式评估错误。 只有在明确指定TRIBOOL(FALSE)时才能正确工作。
故事的寓意:编译器根据值选择类型。
auto a = 0? indeterminate : false; // type function pointer
auto b = 0? indeterminate : true; // type bool
.
输出:
- indet:1?不确定:假
- indet:0?不确定:假
- 是的:1?不确定:真正的
- 是的:0?不确定:真正的
- indet:1?不确定:TRIBOOL(假)
- 假:0?不确定:TRIBOOL(假)
- indet:1?不确定:TRIBOOL(TRUE)
- 是的:0?不确定:TRIBOOL(TRUE)
源代码:
#include <iostream>
#include <boost/logic/tribool.hpp>
using namespace boost;
void test_tribool( const tribool& v, const char* name )
{
const char* s;
if ( v )
s = "true";
else if ( !v )
s = "false";
else
s = "indet";
std::cout << s << "\t: " << name << std::endl;
}
#define TEST_TRIBOOL( ... ) test_tribool( (__VA_ARGS__), #__VA_ARGS__ );
int main(int argc, char** argv)
{
TEST_TRIBOOL( 1? indeterminate : false );
TEST_TRIBOOL( 0? indeterminate : false );
// warning C4305: ':' : truncation from 'bool (__cdecl *)(boost::logic::tribool,boost::logic::detail::indeterminate_t)' to 'bool'
TEST_TRIBOOL( 1? indeterminate : true );
// warning C4305: ':' : truncation from 'bool (__cdecl *)(boost::logic::tribool,boost::logic::detail::indeterminate_t)' to 'bool'
TEST_TRIBOOL( 0? indeterminate : true );
TEST_TRIBOOL( 1? indeterminate : tribool(false) );
TEST_TRIBOOL( 0? indeterminate : tribool(false) );
TEST_TRIBOOL( 1? indeterminate : tribool(true) );
TEST_TRIBOOL( 0? indeterminate : tribool(true) );
return 0;
}
.解决方案
这些是不同的类型,MSVC应该是正确的,给你一个关于这个的警告;从自己自己的文档:
The following rules apply to the second and third expressions: If both expressions are of the same type, the result is of that type. If both expressions are of arithmetic or enumeration types, the usual arithmetic conversions (covered in Arithmetic Conversions) are performed to convert them to a common type. If both expressions are of pointer types or if one is a pointer type and the other is a constant expression that evaluates to 0, pointer conversions are performed to convert them to a common type. If both expressions are of reference types, reference conversions are performed to convert them to a common type. If both expressions are of type void, the common type is type void. If both expressions are of a given class type, the common type is that class type. Any combinations of second and third operands not in the preceding list are illegal. The type of the result is the common type, and it is an l-value if both the second and third operands are of the same type and both are l-values..
因为您的三元运算符不会返回相同类型,因为BOOL的组合和不确定,结果经历了可能与
匹配的转换If both expressions are of pointer types or if one is a pointer type and the other is a constant expression that evaluates to 0, pointer conversions are performed to convert them to a common type..
匹配,
typedef bool (*indeterminate_keyword_t)(tribool, detail::indeterminate_t);
.
在 tribool.hpp 。它是“评估”的函数指针而不是世代odicetagcode值。
所以,必须使false
运算符返回相同类型。更改宏观,看起来像这样:
TEST_TRIBOOL( 1 ? tribool(indeterminate) : tribool(false));
.
或或者,
const tribool t_indet(indeterminate);
const tribool t_false(false);
const tribool t_true(true);
TEST_TRIBOOL( 1 ? t_indet : t_false );
TEST_TRIBOOL( 0 ? t_indet : t_false );
...
. 不隶属于 StackOverflow