1

我正在重载<<以打印自定义对象(在本例中为自定义类的实例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;
}

错误为“非类型模板参数不是常量表达式”。有没有办法在不对参数进行硬编码的情况下解决这个问题?这不是在编译时会知道的。

4

3 回答 3

1

一个简单的功能怎么样:

string bin_format(int_type value, size_t len);

然后您使用它写入流

out << bin_format(v.signature(), v.degree()-1);

除此之外的任何事情都违反了 KISS 原则,需要仔细证明。例如,如果您设法重复如此频繁地导致动态分配导致问题,您可以编写一个获取流和参数的函数并将单个位写入流,或者您可以在该运算符执行的位置string返回具有重载的代理operator<<格式化和流式传输。顺便说一句,您还可以根据整数类型将该函数转换为模板,以便您至少可以设置所需的最大位数。

于 2015-04-07T19:58:52.753 回答
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;
}
于 2015-04-07T19:57:43.867 回答
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
}
于 2015-04-07T19:43:41.780 回答