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

时间:2018-08-12 20:51:20

标签: c++ stdout c++17

我有一个变量x

它可以是charuint8_tstd::string类型。

我希望使用涉及std::cout 的相同表达式输出数字(而不是字符)。这是因为我在生成的代码中使用了此表达式。

在代码生成时,我目前不知道xcharuint8_t还是std::string

如果std::cout << x << std::endl的类型为x

char不起作用,因为它将输出字符而不是数字。

如果std::cout << +x << std::endl的类型为x,则

std::string不起作用。

如果std::cout << (typeid(x) == typeid(uint8_t) || typeid(x) == typeid(char) ? +x : x) << std::endl的类型为x,则

std::string不起作用。

如果std::cout << (typeid(x) == typeid(uint8_t) || typeid(x) == typeid(char) ? static_cast<int>(x) : x) << std::endl的类型为x,则

std::string不起作用。

我知道可以通过管道std::coutstd::hex来配置std::boolalpha的各种方式,但是我不知道配置std::cout来输出{ {1}}作为数字,而无需先转换char

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

例如,如果x是65,类型为x,则所需的输出是char,而不是65

3 个答案:

答案 0 :(得分:4)

只需格式化一个帮助程序,然后对要自定义的版本进行专业化处理。例如:

#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";
}

答案 1 :(得分:2)

我想您正在通用环境中工作。因此,您的基本问题是您需要静态分派。三元组运算符? :不提供此功能。它会在运行时进行评估,并且始终会调用相同的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。

答案 2 :(得分:0)

此解决方案对我有用。它将output函数与模板特殊化和if constexpr一起使用,将char作为数字输出:

#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;
}

感谢DietmarKühl和Marcel提供的有用答案。