0

最终目标如下:我希望能够for_eachoperator<<. 我意识到我可以使用ostream_iterator,但我想看看没有它是否可能。

一些示例代码,以便您了解我想要做什么:

#include <algorithm>
#include <iostream>
#include <functional>
#include <vector>

using std::bind;
using std::ref;
using std::placeholders::_1;
using std::for_each;
using std::ostream;
using std::cout;
using std::endl;
using std::vector;

class C {
    private:
        int x;
    public:
        C() : x(0) { }
        C(int x) : x(x) { }

    friend ostream& operator<<(ostream& out, const C& c);
};

ostream& operator<<(ostream& out, const C& c) {
    return out << c.x << endl;
}

int main() {
    vector<C> v;
    v.push_back(C(1));
    v.push_back(C());

    for_each(v.begin(), v.end(), bind(&ostream::operator<<, ref(cout), _1));

    return 0;
}

我没有成功尝试的一件事(上图):

bind(static_cast<ostream& (ostream::*)(ostream&, const C&)>(&ostream::operator<<), ref(cout), _1)

4

3 回答 3

3

您可以只使用 lambda,如:

for_each(v.begin(), v.end(), [](C const& c){ cout << c; });

for_each就个人而言,当我的意图是访问序列中的每个元素时,我更喜欢使用它。

于 2013-02-14T20:12:06.107 回答
3

您指定错误operator<<;你已经指定ostream::operator<<了,但你operator<<是免费的,即::operator<<

这适用于您当前的程序:

for_each(v.begin(), v.end(), bind(&::operator<<, ref(cout), _1));

但是,如果您添加更多 free operator<<s,那么它将再次失败,因为bind无法确定operator<<是什么意思。在这种情况下,您必须通过显式特化来指定:

for_each(v.begin(), v.end(), bind<ostream&(*)(ostream&, const C&)>(&::operator<<, ref(cout), _1));

等效地,您可以使用static_cast<ostream&(*)(ostream&, const C&)>(&::operator<<).

问题是<<instd::cout << c既可以是自由运算符也可以是成员运算符,没有办法先验地知道哪个。 ostream_iterator通过生成允许编译器决定如何评估表达式的代码来工作;同样,如果您使用 lambda 或仅使用范围 for 循环。

于 2013-02-14T20:18:10.837 回答
1

这里有什么问题吗?

for (auto c :v) cout<<c;

或在这里:

for (const auto& c :v) cout<<c;

或在这里:

for (C const& c :v) cout<<c;
于 2013-02-15T11:08:34.330 回答