与条件运算符一起使用时,动作不一致
decltype acting inconsistent when used in conjunction with conditional operator
在研究c++ 11的一些新特性时,我注意到新的decltype关键字及其与条件操作符的交互有一些奇怪之处。
看到下面程序的输出,我非常惊讶:
#include <iostream>
#include <map>
int main(void)
{
// set up a map that associates the internal compiler-defined type_info name with a human readable name
std::map <std::string, std::string> types;
types[typeid(decltype(static_cast<unsigned char >(0))).name()] = "unsigned char";
types[typeid(decltype(static_cast<unsigned short >(0))).name()] = "unsigned short";
types[typeid(decltype(static_cast<short >(0))).name()] = "short";
types[typeid(decltype(static_cast<unsigned int >(0))).name()] = "unsigned int";
types[typeid(decltype(static_cast<int >(0))).name()] = "int";
types[typeid(decltype(static_cast<float >(0))).name()] = "float";
types[typeid(decltype(static_cast<double >(0))).name()] = "double";
types[typeid(decltype(static_cast<bool >(0))).name()] = "bool";
std::cout << "Should be unsigned char : " << types[typeid(decltype(static_cast<unsigned char >(0))).name()] << std::endl;
std::cout << "Should be unsigned short: " << types[typeid(decltype(static_cast<unsigned short>(0))).name()] << std::endl;
std::cout << "Should be short : " << types[typeid(decltype(static_cast<short >(0))).name()] << std::endl;
std::cout << "Should be unsigned int : " << types[typeid(decltype(static_cast<unsigned int >(0))).name()] << std::endl;
std::cout << "Should be int : " << types[typeid(decltype(static_cast<int >(0))).name()] << std::endl;
std::cout << "Should be float : " << types[typeid(decltype(static_cast<float >(0))).name()] << std::endl;
std::cout << "Should be double : " << types[typeid(decltype(static_cast<double >(0))).name()] << std::endl;
std::cout << "Expecting unsigned short: " << types[typeid(decltype(
false ? static_cast<unsigned char >(0) :
true ? static_cast<unsigned short >(0) :
false ? static_cast< short >(0) :
false ? static_cast<unsigned int >(0) :
false ? static_cast< int >(0) :
false ? static_cast< float >(0) :
false ? static_cast< double>(0) :
static_cast< bool >(0)
)).name()] << std::endl;
}
这导致了令人惊讶的输出:
Should be unsigned char : unsigned char
Should be unsigned short: unsigned short
Should be short : short
Should be unsigned int : unsigned int
Should be int : int
Should be float : float
Should be double : double
Expecting unsigned short: double
我希望看到如下输出(注意最后一行):
Should be unsigned char : unsigned char
Should be unsigned short: unsigned short
Should be short : short
Should be unsigned int : unsigned int
Should be int : int
Should be float : float
Should be double : double
Expecting unsigned short: unsigned short
有人知道为什么会发生这种情况吗?
你需要改变你的期望。条件表达式的类型仅取决于其操作数的类型,而不取决于操作数的值。
有许多规则用于根据第二个和第三个操作数的类型确定条件表达式的公共类型。第二个和第三个操作数的值,即使是常量表达式,也不会被考虑。
您应该查阅标准以了解确定通用类型的规则的详细信息。如果找不到通用类型,程序通常是病态的。
三元表达式的结果类型与最后两个参数的类型相同。在c++ 11中,有一个std::common_type
trait可以获得该类型(如果我没记错的话,它实际上是作为decltype( false ? x : y )
实现的)。
您在最后一个表达式中得到的是bool
, int
, short
, double
等常见的类型…
条件表达式的结果类型是最后两个参数的类型。最后两个参数需要是相同的类型。在您的示例中,所有内容都被提升为两倍以满足此要求。如果在表达式中添加了不能隐式强制为double的类型(例如void*),将会出现编译错误。
在这种情况下,Decltype是一种转移注意力的方法。此行为继承自c。相关文章:
- 大于65535的C++数组[size]引发不一致的溢出
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在 C++(和 C)中进行类型转换时明显不一致
- 填充上编译器生成的复制构造函数之间的不一致
- 犰狳的 print() 方法和 cout 在从 Rcpp 调用时顺序不一致
- CreateDIBSection为同一图像返回不一致的位图位值
- 编译器调用复制运算符而不是移动运算符
- C++中的条件运算符 ( ? : ) 可以编译时吗?
- 不显示匹配运算符
- 条件运算符不允许程序终止
- 与条件 noexcept 和重载不一致
- 如果有条件使用String.length()的条件,为什么不一致地评估这一点
- 为什么C++不允许在条件运算符中进行隐式列表初始化?
- C++循环多个条件不一致
- 使用三元条件运算符时操作数类型不兼容
- 我对指针/引用中C++"&"运算符的不一致应用感到困惑?
- 在 c++ 中,条件运算符不支持指针
- 声明不能发生在条件运算符表达式内部
- 与条件运算符一起使用时,动作不一致
- std::设置不一致的运算符<