输出一个数字,该数字可能是三种类型之一

Output a number that may be one of three types

本文关键字:数字 三种 类型 一个 输出      更新时间:2023-10-16

我有一个变量x.

它可以是char型、uint8_t型或std::string型。

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

在代码生成时,我目前不知道x是否会charuint8_tstd::string

如果x是类型char,则std::cout << x << std::endl不起作用,因为它将输出字符而不是数字。

如果x类型为std::string,则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不起作用。

我知道可以通过管道std::hexstd::boolalpha以各种方式配置std::cout,但我知道没有可能的方法可以将std::cout配置为将char输出为数字,而无需先转换char

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

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

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

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

我猜你是在通用上下文中工作。所以你的基本问题是你需要静态调度。三元组运算符? :不提供此信息。它在运行时计算,并将始终调用相同的operator<<

所以你有两个选择:

  1. 使用具有部分专用化的帮助程序类

  2. 使用静态如果,即

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

后者需要C++17。

这个解决方案对我有用。它通过使用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;
}

感谢Dietmar Kühl和Marcel的有用答案。