输出一个数字,该数字可能是三种类型之一
Output a number that may be one of three types
我有一个变量x
.
它可以是char
型、uint8_t
型或std::string
型。
我希望输出数字(不是字符(,使用相同的表达式涉及std::cout
.这是因为我在生成的代码中使用此表达式。
在代码生成时,我目前不知道x
是否会char
、uint8_t
或std::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::hex
或std::boolalpha
以各种方式配置std::cout
,但我知道没有可能的方法可以将std::cout
配置为将char
输出为数字,而无需先转换char
。
有没有办法使用反射、运算符重载、模板或其他东西 这样就可以有一个统一的语句来输出x
,作为一个数字?
例如,如果类型为char
的x
为 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<<
。
所以你有两个选择:
-
使用具有部分专用化的帮助程序类。
-
使用静态如果,即:
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的有用答案。
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 我可以使用 g++ 进行三种比较 (<=>) 吗?
- 多维数组存储三种不同的数据类型?
- 如何使一个函数具有三种不同的输出条件?
- 输出一个数字,该数字可能是三种类型之一
- 如何创建一个包含三种不同类型的向量的向量
- 当一种方法有三种返回可能性时该怎么办?
- 三种类型之间的隐式转换交互
- 可以使用 std::p air 保存三种数据类型的向量
- 解释C 中三种返回类型的方法
- 如何使用“英特尔C++编译器”(ICC)在三种方法上使用SFINAE
- 加载动态链接库的第三种方法?大头针
- 如何以及何时使用(或不使用)三种特定情况的例外
- 我使用三种内存清除变体.他们都安全吗?我可以得到内存泄漏吗?
- 在给定前景色和背景色的情况下,我如何计算第三种颜色
- 如何使用条件运算符表达三种情况
- 为什么这个为三种整数类型重载的函数无法编译?
- 创建一个有三种方法可供选择的加密程序!它有问题,我不知道如何解决
- 三种显式上转换到私有基类的区别
- 调用方法的这三种语法形式之间有什么区别?