当与条件运算符一起使用时,decltype表示不一致

use*_*113 0 c++ decltype c++11

在研究一些新的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;
}
Run Code Online (Sandbox Code Playgroud)

这导致了惊人的输出:

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
Run Code Online (Sandbox Code Playgroud)

我本来期望看到以下输出(注意最后一行):

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
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么会发生这种情况?我正在使用GNU g ++.

CB *_*ley 8

你需要改变你的期望.该类型的条件表达式只取决于它的类型的操作数,不是它的操作数的值.

有许多规则用于根据第二个和第三个操作数的类型确定条件表达式的公共类型.第二个和第三个操作数的值,即使它们是常量表达式,也不予考虑.

有关确定常见类型的规则的详细信息,请参阅标准.如果找不到常见类型,程序通常是格式错误的.