c++ 如何使用std::copy在控制台上显示自己数据类型的std::vector的内容和名称?

6za6bjd0  于 2023-01-15  发布在  其他
关注(0)|答案(2)|浏览(121)

我希望使用std::copy显示std::vector<User>的内容,方法与下面代码中通过std::for_each实现的方法类似。

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
class User {
private:
    std::string m_sName;
public:
    User(std::string sName):m_sName(sName) {}
    std::string GetName()const {
        return m_sName;
    }
};
int main()
{
    std::vector<User> vectNames;
    vectNames.emplace_back("Jack");
    vectNames.emplace_back("George");
    vectNames.emplace_back("Jose");
//How can I get std::copy to do what the std::for_each is doing?
    std::copy(vectNames.begin(), vectNames.end(), std::ostream_iterator<User>(std::cout, "\n"));
//The following line is what I really would like std::copy to do. 
    std::for_each(vectNames.begin(), vectNames.end(), [](const User &user) {std::cout << user.GetName() << "\n"; });
    
}
unguejic

unguejic1#

您可以简单地重载ostream运算符:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

class User {
private:
    std::string m_sName;
public:
    User(std::string sName):m_sName(sName) {}
    std::string GetName()const {
        return m_sName;
    }
    void print(std::ostream& where) const
        { where << m_sName; }
};

/// Overloaded ostream operator
std::ostream& operator<< (std::ostream& out, const User& user)
{
    user.print(out);
    return out;
}

int main()
{
    std::vector<User> vectNames;
    vectNames.emplace_back("Jack");
    vectNames.emplace_back("George");
    vectNames.emplace_back("Jose");
    
    std::copy(vectNames.begin(), vectNames.end(), std::ostream_iterator<User>(std::cout, "\n"));
}

一般来说,我总是有一个重载的ostream作为存储和输出信息的类的一部分。

ghhkc1vu

ghhkc1vu2#

因为你的评论 * 我是一个新的程序员,正在尝试不同的想法 *,我张贴这个答案作为一个替代方法,其中还显示了一些算法,你可能会热情。
我认为,如果您想同时完成这两个任务,那么std::copy不是合适的工具
1.对集合中的对象调用成员函数,并且仅在此之后调用
1.复制/打印到屏幕
atru's answer中的一种方法可能是最好的方法,它基本上只使用std::copy解决了第2点(根据您的问题,您已经知道如何做到这一点),而通过重载<<解决了第1点,这就成功了。
我提出的替代方案基于这样的想法:“在集合的每个对象上调用成员函数”实际上是对该集合的一个 transform 操作。然而,std::transform就像std::copy一样作用于迭代器,而不是作用于范围,因此它们不能很容易地相互组合。
Boost提供了boost::copyboost::adaptors::transformed,可以实现以下功能:

boost::copy(
        vectNames | transformed([](auto const& x){ return x.GetName(); }),
        std::ostream_iterator<std::string>(std::cout, "\n")
    );

其中vectNames通过管道传输到transformedtransformed将lambda应用于集合的每个元素,从而产生一个新的临时集合,该临时集合是boost::copy的参数。如果要使用std::copy,则必须将临时集合存储在某个地方,例如temp。然后将其迭代器temp.begin()temp.end()传递给std::copy
完整的示例如下所示,我希望它能给予您对不同的、功能更强的方法有所了解。

#include <functional>
#include <iostream>
#include <vector>
#include <string>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/copy.hpp>
class User {
private:
    std::string m_sName;
public:
    User(std::string sName):m_sName(sName) {}
    std::string GetName()const {
        return m_sName;
    }
};
int main()
{
    std::vector<User> vectNames;
    vectNames.emplace_back("Jack");
    vectNames.emplace_back("George");
    vectNames.emplace_back("Jose");

    using boost::adaptors::transformed;
    boost::copy(
        vectNames | transformed([](auto const& x){ return x.GetName(); }),
        std::ostream_iterator<std::string>(std::cout, "\n")
    );
}

相关问题