Hey guys,

What am I doing wrong here?

sss.hpp

#include <fstream>
#include <string>
#include <map>

namespace sss {
    using namespace std;
    class node {
    public:
        multimap<string, string>  values;
        multimap<string, node>    children;

        string &value(const string name, size_t index = 0);
        node &child(const string name, size_t index = 0);

    private:
    
        template <typename T1, typename T2>
        T2 &searchInsert(multimap<T1, T2> &container, const T1 &name, size_t index = 0) {
            typename multimap<T1, T2>::iterator it = container.find(name);

            //found none, insert...
            if (it == container.end()) {
                it = container.insert(pair<T1, T2>(name, T2()));
                return it->second;
            }

            //found one, multimap is sorted, iterate to index-th element or the end.
            for (size_t i = 0; i < index; i++) {
                it++;
                if (it == container.end()) {
                    it = container.insert(pair<T1, T2>(name, T2()));
                    return it->second;
                }
            }

            return it->second;
        }
    };
}

sss.cpp

#include <iostream>
#include <fstream>
#include <map>
#include <string>

#include "sss.hpp"

using namespace std;
using sss::node;

string& node::value(const string name, size_t index) {
    return searchInsert<string, string>(values, name, index);
}

node& node::child(const string name, size_t index) {
    return searchInsert<string, node>(values, name, index);
}

It won't compile with the following errors:

\Code\SSSParser\sss.cpp error: no matching function for call to `sss::node::searchInsert(std::multimap<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >&, const std::string&, size_t&)'

I don't really get what it's trying to do.

Thanks in advance,

Okay dat was stoopid.

node& node::child(const string name, size_t index) {
    return searchInsert<string, node>(values, name, index);
}

Should of course be..

node& node::child(const string name, size_t index) {
    return searchInsert<string, node>(children, name, index);
}

No wonder.

Hehe, back again. Templates are difficult if you're not precise I guess. I'm stuck on this one:

sss.hpp

#include <string>
#include <map>
#include <stdexcept>

#ifndef SSSHPP
#define SSSHPP

namespace sss {
    using namespace std;

    class node {

    public:
        multimap<string, string>  values;
        multimap<string, node>    children;

    private:
        template <typename T1, typename T2>
        T2 &get_indexed(multimap<T1, T2> &container, T1 &key, size_t index = 0) {
            size_t count = container.count(key);

            if (count != 0 && count-1 >= index) {
                //it exists and index is within range
                //grab iterator, increment index times and return the node belonging to that.
                typename multimap<T1, T2>::iterator it = container.find(key);
                while (index--) it++;
                return it->second;
            } else {
                //Doesn't exist: throw OOR
                throw out_of_range((string)"get_indexed->"+"Element " + key + "doesn't exist!");
            }
        }
    };
}

#endif // SSSHPP

Call with:

sss.cpp

string &node::getValue(const string &name, size_t index) throw (out_of_range) {
    get_indexed<string, string>(values, name, index);
}

Doesn't compile with:

Code\SSSParser\sss.cpp In member function `std::string& sss::node::getValue(const std::string&, size_t)':
Code\SSSParser\sss.cpp error: no matching function for call to `sss::node::get_indexed(std::multimap<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >&, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, size_t&)

Ugh, fixed it, I forgot the const. With normal functions the error messages are a lot clearer in GCC.. hope they "fix" this soon.

Here's the working code:

//...
    private:
        template <typename T1, typename T2>
        T2 &get_indexed(multimap<T1, T2> &container, const T1 &key, size_t index = 0) {
            size_t count = container.count(key);
//...
This article has been dead for over six months. Start a new discussion instead.