iomanip函数是如何实现的?

9
一些标准的函数需要一个参数。我想知道如何实现这一点,例如,我能否使用一个函数来做类似的事情?那确实是我在这个答案中需要的解决方案,但我无法弄清楚如何做到这一点。例如,在http://en.cppreference.com中查找setw函数的定义时,它将返回类型列为“未指定”,并且它也只列出一个参数,而不是还有一个stream&参数。这是如何工作的?
读者注意:这个问题有一个很好的答案,但对于查找这个问题的个人来说,与ios_base提供的以下功能结合使用才有用:

1
他们实际上在使用辅助函数/类和专门的 operator<<() / operator>>() 重载进行这些操作。 - πάντα ῥεῖ
1
与自定义格式选项不同,流具有width成员函数,作为访问器和变异器。据我所知,自定义添加几乎必须使用xalloc等。 - chris
@chris 你所说的xalloc到底是什么鬼?我看了http://www.cplusplus.com的[xalloc描述](http://www.cplusplus.com/reference/ios/ios_base/xalloc/),但对我来说并没有什么帮助。 - Jonathan Mee
1
@JonathanMee,我从未使用过它。据我所知,这只是一种在流中存储任意信息的方法。pword页面有一个示例,cppreference也有。 - chris
@chris,我只能通过您的评论使用这里的答案。非常感谢你!我将它们并入问题中,以帮助未来的读者沿着比查看评论更容易的路径前进。 - Jonathan Mee
1个回答

10

这是一个简单的示例,演示了如何使用类定义一个带有一个参数的用户自定义操作符:

#include <iostream>

class putX // injects some `X`s into the stream
{
    std::size_t _n;
public:
    explicit putX(std::size_t n): _n(n) {}
    std::size_t getn() const {return _n;}
    friend std::ostream& operator<<(std::ostream& os, const putX& obj)
    {
        std::size_t n = obj.getn();
        for (std::size_t i = 0; i < n; ++i)
            os << 'X';
        return os;
    }
};

int main()
{
    std::cout << putX(10) << " test " << putX(10);
}

没有参数的操作符可以直接实现为

std::ostream& custom_manip(std::ostream& os) { // do something with os and return os;}

那是因为 basic_ostream::operator<< 有一个重载,它以指向函数的指针 std::ostream& (*fp)(std::ostream&) 作为其右操作数(例如,一个控制器)。

PS:N. Josuttis 的《C++标准库》详细描述了操作符和自定义操作符的工作原理。请参见第15.6.3节用户定义的操作符


你可以只使用一个函数,如果特定的函数指针使用了运算符重载,则可以实现。这适用于没有参数的情况。 - πάντα ῥεῖ
1
@πάνταῥεῖ 我指的是需要参数的操作符重载。在这种情况下,您需要重载 std::ostream& std::ostream::operator<<( std::ostream& (*fp)(std::ostream&, param1, param2... )),但这是不允许的。 - vsoftco
@RemyLebeau 我认为可以,至少我相信这不违反标准。这是我偶然发现的一些东西:http://stackoverflow.com/a/12182338/3093378 - vsoftco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接