我正在重载<<
来打印自定义对象(在本例中是自定义类Vertex
的实例)。作为其中的一部分,我想打印二进制的给定整数。我更倾向于使用std::bitset
而不是运行for循环,但我遇到的问题是我有一个特定的大小,每个二进制文件应该取决于实例。这是片段:
std::ostream &
operator<< (std::ostream& os, const Vertex& V) {
os << "(" << std::bitset<4>(V.signature()) << ") :";
for (int e=2; e<V.degree(); ++e) {
os << " [" << e << "]=" << V.neighbor(e) << " ";
}
return os;
}
取代4
代替size_t
,我真的想要V
取决于std::ostream &
operator<< (std::ostream& os, const Vertex& V) {
size_t B = V.degree()-1;
os << "(" << std::bitset<B>(V.signature()) << ") :";
for (int e=2; e<V.degree(); ++e) {
os << " [" << e << "]=" << V.neighbor(e) << " ";
}
return os;
}
。例如,这是我试过的:
{{1}}
错误显示“非类型模板参数不是常量表达式”。有没有办法解决这个问题,而无需对参数进行硬编码?这不是编译时可以知道的东西。
答案 0 :(得分:1)
一个简单的功能怎么样:
string bin_format(int_type value, size_t len);
然后使用
写入流out << bin_format(v.signature(), v.degree()-1);
除此之外的任何事情都违反了KISS原则,需要谨慎对待。例如。如果你设法重复这种情况以至于string
中的动态分配导致问题,你可以写一个函数来获取流和参数并将单个位写入流中,或者你可以返回一个带有重载的代理operator<<
该运算符执行格式化和流式处理。顺便说一句,您也可以根据整数类型将该函数转换为模板,这样您至少可以在所需的位数上设置最大值。
答案 1 :(得分:0)
由于无法将std::bitset<>
与运行时参数一起使用,因此您应该编写自己的“位显示”类/函数。以下是重载流插入operator<<
:
// Display bits at runtime (cannot use std::bitset<> in this case)
#include <algorithm> // for std::reverse
#include <cstddef> // for std::size_t
#include <iostream>
#include <string>
template<typename T>
class disp_bitset
{
std::size_t _size;
T _n;
public:
explicit disp_bitset(std::size_t size, T n): _size(size), _n(n) {}
friend std::ostream& operator<<(std::ostream& os, const disp_bitset& rhs)
{
T tmp = rhs._n;
std::string aux;
for (std::size_t i = 0; i < rhs._size; ++i)
{
aux += (tmp & 0x01) + '0';
tmp = tmp >> 1;
}
std::reverse(aux.begin(), aux.end());
return os << aux;
}
};
int main()
{
disp_bitset<std::size_t> x(8, 41); // size_t 41 on 8 bits
std::cout << x << std::endl;
std::cout << disp_bitset<char>(16, 'a'); // char 'a' on 16 bits
}
答案 2 :(得分:0)
这是一次彻底的黑客攻击,所以我希望有更好的东西,但它似乎现在已经完成了工作。欢迎改进!
std::ostream &
operator<< (std::ostream& os, const Vertex& V) {
std::string bin = std::bitset<16>(V.signature()).to_string();
bin.erase(bin.begin(),bin.end()-V.degree()+1);
os << "(" << bin << ") :";
for (int e=2; e<V.degree(); ++e) {
os << " [" << e << "]=" << V.neighbor(e) << " ";
}
return os;
}