我有一个变量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的有用答案。