代码之家  ›  专栏  ›  技术社区  ›  Alexander ZaLar

输出一个可以是三种类型之一的数字

  •  0
  • Alexander ZaLar  · 技术社区  · 6 年前

    我有个变数 x .

    char , uint8_t std::string .

    我想输出数字(不是字符),使用 std::cout . 这是因为我在生成的代码中使用了这个表达式。

    在代码生成时,我目前不知道 烧焦 , 标准::字符串

    std::cout << x << std::endl 属于类型 烧焦 ,因为它将输出字符而不是数字。

    std::cout << +x << std::endl 属于类型 .

    std::cout << (typeid(x) == typeid(uint8_t) || typeid(x) == typeid(char) ? +x : x) << std::endl 标准::字符串 .

    std::cout << (typeid(x) == typeid(uint8_t) || typeid(x) == typeid(char) ? static_cast<int>(x) : x) << std::endl 不工作,如果 标准::字符串

    我知道 可通过管道以多种方式配置 std::hex std::boolalpha ,但我知道无法配置 标准:cout 烧焦 作为一个数字,不需要 烧焦

    有没有办法使用反射、运算符重载、模板或其他东西 这样就可以有一个统一的语句来输出 ,作为一个数字?

    例如,如果 是65型 ,所需的输出为 65 ,不是 A .

    3 回复  |  直到 6 年前
        1
  •  4
  •   Dietmar Kühl    6 年前

    只需格式化一个助手并专门化您想要适当自定义的版本。例如:

    #include <iostream>
    
    template <typename T>
    struct formatter {
        T const& value;
    };
    
    template <typename T>
    formatter<T> format(T const& value) {
        return formatter<T>{value};
    }
    
    template <typename T>
    std::ostream& operator<< (std::ostream& out, formatter<T> const& v) {
        return out << v.value;
    }
    
    std::ostream& operator<< (std::ostream& out, formatter<char> const& v) {
        return out << int(v.value);
    }
    
    template <std::size_t N>
    std::ostream& operator<< (std::ostream& out, formatter<char[N]> const& v) {
        return out << '\'' << v.value << '\'';
    }
    
    
    int main() {
        std::cout << "char=" << format('c') << " "
                  << "int=" << format(17) << " "
                  << "string=" << format("foo") << " "
                  << "\n";
    }
    
        2
  •  2
  •   Marcel    6 年前

    我猜你是在一般的背景下工作。所以你的基本问题是 ? : 不提供这个。它在运行时进行计算,并始终调用相同的 operator<< .

    1. 使用帮助类

    2. 使用静态if

      if constexpr (std::is_integral<decltype(x)>::value)
        std::cout << static_cast<int>(x) << std::endl;
      else
        std::cout << x << std::endl;
      

    后者需要C++ 17。

        3
  •  0
  •   Alexander ZaLar    6 年前

    这个办法对我有效。它使用 output if constexpr :

    #include <cstdint>
    #include <iostream>
    #include <string>
    
    using namespace std::string_literals;
    
    template <typename T> void output(std::ostream& out, T x)
    {
        if constexpr (std::is_integral<decltype(x)>::value) {
            out << static_cast<int>(x);
        } else {
            out << x;
        }
    }
    
    int main()
    {
        char x = 65;
        uint8_t y = 66;
        std::string z = "hi"s;
    
        // output: A
        std::cout << x << std::endl;
    
        // output: 65
        output(std::cout, x);
        std::cout << std::endl;
    
        // output: B
        std::cout << y << std::endl;
    
        // output: 66
        output(std::cout, y);
        std::cout << std::endl;
    
        // output: "hi"
        output(std::cout, z);
        std::cout << std::endl;
    
        return 0;
    }
    

    感谢Dietmar Khl和Marcel提供的有用答案。