我有一个变量x
。
它可以是char
,uint8_t
或std::string
类型。
我希望使用涉及std::cout
的相同表达式输出数字(而不是字符)。这是因为我在生成的代码中使用了此表达式。
在代码生成时,我目前不知道x
是char
,uint8_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::cout
或std::hex
来配置std::boolalpha
的各种方式,但是我不知道配置std::cout
来输出{ {1}}作为数字,而无需先转换char
。
有没有一种方法可以使用反射,运算符重载,模板或其他东西
这样一个人就可以有一个统一的语句来输出char
作为数字?
例如,如果x
是65,类型为x
,则所需的输出是char
,而不是65
。
答案 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<<
。
因此,您有两种选择:
使用部分专门化的帮助程序类。
使用静态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提供的有用答案。