迭代内部方法的向量

时间:2015-05-24 19:43:20

标签: c++ templates iterator

我目前正在学习C ++,我有以下工作代码:

int main(int argc, char** argv) {
        map<unsigned int, list<mpz_class>> otp;

        // .....

        for(auto it1 = otp.begin(); it1 != otp.end(); ++it1) {
                bool first = true;
                for(auto it2 = it1->second.begin(); it2 != it1->second.end(); ++it2) {
                        if (!first) {
                                cout << ", ";
                        } else {
                                first = false;
                        }
                        cout << *it2;
                }
        }
}

我想把列表的打印放到一个函数中。

这是我的尝试:

void prnt_list(vector it, ostream outstr, string delimiter) {
        bool first = true;
        for(auto it2 = it.begin(); it2 != it.end(); ++it2) {
                if (!first) {
                        outstr << delimiter;
                } else {
                        first = false;
                }
                outstr << *it2;
        }
}

int main(int argc, char** argv) {
    map<unsigned int, list<mpz_class>> otp;

    // .....

    for(auto it1 = otp.begin(); it1 != otp.end(); ++it1) {
        prnt_list(it1->second, cout, ", ");
    }
)

它无法编译:

error: variable or field 'prnt_list' declared void
error: missing template arguments before 'it'
error: expected primary-expression before 'outstr'
error: expected primary-expression before 'delimiter'

然后我尝试了这个:

template <typename T>
void prnt_list<T>(vector<T> it, ostream outstr, string delimiter) {
    ...
}

但它也行不通。

另外,我也不喜欢强制模板,因为我想允许任何向量。如果我能以某种方式使用auto关键字,那会更舒服。

4 个答案:

答案 0 :(得分:3)

该功能可以通过以下方式定义

std::ostream & prnt_list( const std::list<mpz_class> &lst, 
                          std::ostream &os = std::cout, 
                          const char *delimiter = ", " ) 
{
    bool first = true;

    for ( const auto &obj : lst ) 
    {
        if ( first ) first = false;
        else os << delimiter;

        os << obj;
    }

    return os;
}

并调用

for ( const auto &p : otp ) prnt_list( p.second ) << std::endl;

您可以为任何容器编写常规函数。例如

template <class Container>
std::ostream & prnt_list( const Container &container, 
                          std::ostream &os = std::cout, 
                          const char *delimiter = ", " ) 
{
    bool first = true;

    for ( const auto &obj : container ) 
    {
        if ( first ) first = false;
        else os << delimiter;

        os << obj;
    }

    return os;
}

至于你的代码,那么至少没有声明标识符向量,并且流不可复制。

答案 1 :(得分:1)

您要向期望list的函数发送vector 通用看起来像这样:

template <typename T>
void prnt_list(const T& it, std::ostream& outstr, const std::string& delimiter)
{
    bool first = true;
    for( auto&& obj : it ) {
        if (!first)
            outstr << delimiter;
        else
            first = false;
        outstr << obj;
    }
}

另请注意,必须为<<

定义mpz_class

它需要标题<string><iostream>

答案 2 :(得分:1)

问题是:

map<unsigned int, list<mpz_class>> otp;

作为第二个列表,作为prnt_list的第一个参数,你有vector。为什么呢?

要修复这些错误,请使用以下签名进行prnt_list:

template<typename T>
void prnt_list(list<T>& it, ostream& outstr, string delimiter) {

答案 3 :(得分:1)

expandind对弗拉德的回答 - 允许print_list参与<profile> <id>manager</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <phase>test</phase> <goals> <goal>java</goal> </goals> </execution> </executions> <configuration> <mainClass>system.Computer</mainClass> <commandlineArgs>"hello"</commandlineArgs> </configuration> </plugin> </plugins> </build> </profile> ostream链:

<<

预期产出:

#include <iostream>
#include <list>

namespace detail {

    // it's called a simple list printer because it assumes that
    // list::value_type is printable
    template<class T, class A>
    struct simple_list_printer {
        simple_list_printer(const std::list<T, A>& list, std::string delimiter)
        : _list { list }
        , _delimiter { delimiter }
        {}

        void write(std::ostream& os) const {
            bool first = true;

            for ( const auto &obj : _list )
            {
                if ( first ) first = false;
                else os << _delimiter;

                os << obj;
            }
        }
    private:
        const std::list<T, A>& _list;
        std::string _delimiter;
    };

    // stream an simple_list_printer to any ostream
    template<class T, class A>
    inline std::ostream& operator<<(std::ostream& os, const simple_list_printer<T, A>& slp)
    {
        slp.write(os);
        return os;
    }
}

// a mockup of mpz_class
struct mpz_class {

    void write(std::ostream& os) const {
        os << "{ i am an mpz - write my members here }";
    }
};

// stream an mpz to any ostream
inline std::ostream& operator<<(std::ostream& os, const mpz_class& mpz)
{
    mpz.write(os);
    return os;
}

// construct a simple_list_printer
template<class A>
detail::simple_list_printer<mpz_class, A>
print_list(const std::list<mpz_class, A>& list, std::string delimiter = std::string { ", " })
{
    return { list, std::move(delimiter) };
}

int main()
{
    std::list<mpz_class> a { {}, {} };

    std::cout << print_list(a) << std::endl;
    std::cerr << print_list(a) << std::endl;
    std::clog << print_list(a) << std::endl;

    std::cout << print_list(a, "\n") << std::endl;
    std::cout << std::endl;
    std::cerr << print_list(a, " * ") << std::endl;
    std::clog << print_list(a, " <--> ") << std::endl;

    return 0;
}