c++ - 需要使上下文可用于 C++ ostream 插入运算符

标签 c++ chaining ostream insertion

对于我正在处理的 API,我希望允许用户将自定义对象插入到 ostream 中,但这些对象本身没有任何意义,而且内存受限而无法包含上下文的附加指针或引用。 (想想在内存有限的嵌入式系统中有数千万个 16-/32-/48 位对象。)

假设用户初始化底层上下文,并查找这些对象之一:

DDB ddb("xc5vlx330t");
Tilewire tw = ddb.lookUpTilewire("DSP_X34Y0", "DSP_IMUX_B5_3");
...
std::cout << complexDataStructure;

在一个完全不同的范围内,可能嵌套在远离用户显式代码的地方,我们可能需要将对象插入到 ostream 中,而 ddb 不可用。

os << tw;

tw封装的实际值是97,594,974,但是想要的输出是这样的:

DSP_IMUX_B5_3@[263,84] DSP "DSP_X34Y0" (1488@77406)

为了使其工作,适当的插入运算符需要访问 ddb,但它不能依赖静态或全局变量或函数(出于多线程原因)。我喜欢做的是允许用户请求和使用像这样的流包装器:​​

ostream& wrappedCout = ddb.getWrappedOstream(std::cout);

返回的 ostream 子类将包含对 ddb 的引用,供需要它的特殊流插入器使用,以及对原始流的引用——在本例中为 std::cout——它会在哪里转发其所有输出。

不幸的是,我提出的继承或组合方案编码起来很麻烦(不是一个大问题),并且可能对用户有问题(一个更大的问题)。关于如何优雅地使 ddb 可用于插入运算符的任何建议?我对 boost.Iostreams 知之甚少,但不确定它是否对我有帮助。

最佳答案

编写一个自定义流操纵器,使用 iword/pword 机制存储对 ddb 的引用。这是一个示例,您需要在多线程程序中围绕 iwork_indexes 映射添加锁定。

class dbb
{
public:
    explicit dbb(int value) : m_value(value) {}
    int value() const { return m_value; }
private:
    int m_value;
};

class dbb_reliant_type
{
public:
    dbb_reliant_type(const std::string& value) : m_value(value) {}
    const std::string& value() const { return m_value; }
private:
    std::string m_value;
};

typedef std::map<std::ostream*, int> iword_map;
iword_map iword_indexes;

inline int get_iword_index(std::ostream& os)
{
    iword_map::const_iterator index = iword_indexes.find(&os);

    if(index == iword_indexes.end())
    {
        std::pair<iword_map::iterator, bool> inserted = iword_indexes.insert(std::make_pair(&os, os.xalloc()));
        index = inserted.first;
    }

    return index->second;
}


inline std::ostream& operator<<(std::ostream& os, const dbb& value)
{
    const int index = get_iword_index(os);

    if(os.pword(index) == 0)
        os.pword(index) = &const_cast<dbb&>(value);

    return os;
}

std::ostream& operator<<(std::ostream& os, const dbb_reliant_type& value)
{
    const int index = get_iword_index(os);
    dbb* deebeebee = reinterpret_cast<dbb*>(os.pword(index));
    os << value.value() << "(" << deebeebee->value() << ")";
    return os;
}

int main(int, char**)
{
    dbb deebeebee(5);
    dbb_reliant_type variable("blah");
    std::cout << deebeebee << variable << std::endl;
    return 0;
}

关于c++ - 需要使上下文可用于 C++ ostream 插入运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3114460/

相关文章:

c++ - const 变量的 static_assert

c++ - 用于将多态基类的子类数组传递到构造函数中的最简单语法

php - 具有不同返回值的函数链接?

Javascript 继承 : call super-constructor or use prototype chain?

C++,在 CBuilder 2010 中传递参数时出现 ostream 错误

C++调用函数指针

c++ - 如何实现两个第三方类型之间的转换?

javascript - 如何在 jQuery 中进行 if-then 简写?这些可以链接吗?

c++ - 为什么打印c样式字符串的 'address of index n'导致输出子字符串

c++ - C++中具有相同参数类型的函数重载