0

I am creating my own tree-like container in C++. Here is an outline of how I imagine it's structure:

//==========================================================
// Concept
//==========================================================
//
// RootNode -> Attributes
//          -> Nodes -> Attributes
//                   -> Nodes -> Attributes
//                            -> Nodes
//                             
// etc...
//==========================================================

I have named the type DataTree for now. The header looks like this:

#pragma once

#include <map>
#include <set>
#include <string>

namespace LB{
    class DataTree;
    struct DataTreeComparitor{
        bool operator () (DataTree const & lhs, DataTree const & rhs) const;
        bool operator () (std::string const & lhs, DataTree const & rhs) const;
        bool operator () (DataTree const & lhs, std::string  const & rhs) const;
    };
    class DataTree{
    public:
        template <typename Type>
        Type getAttribute(std::string const & name) const{
            static_cast<Type>(*m_attributes.find(name));
        }

        DataTree getChild(std::string const & name) const;

        std::string getName(void) const;

    private:
        std::string m_name;

        std::multimap<std::string, std::string> m_attributes;
        std::multiset<DataTree, DataTreeComparitor> m_children;
    };
}

I would like to find elements in the container m_children using an std::string, which DataTreeComparitor would compare against the result of getName().

However, when trying to call find() on m_children, I get the following error from mingw32:

    C:/Users/Joshua/Documents/BitBucket/LBC++/LBC++/DataTree.cpp:17:31: error: no matching function for call to 'std::multiset<LB::DataTree, LB::DataTreeComparitor>::find(const string&) const'

And this using MSVC:

    2   IntelliSense: no instance of overloaded function "std::multiset<_Kty, _Pr, _Alloc>::find [with _Kty=LB::DataTree, _Pr=LB::DataTreeComparitor, _Alloc=std::allocator<LB::DataTree>]" matches the argument list
            argument types are: (const std::string)
            object type is: const std::multiset<LB::DataTree, LB::DataTreeComparitor, std::allocator<LB::DataTree>> c:\Users\Joshua\Documents\Visual Studio 2013\Projects\Project1\Project1\Source.cpp  46  21  Project1

Here is the implementation, with the problem line indicated through a comment:

#include "DataTree.h"

namespace LB{
    bool DataTreeComparitor::operator () (DataTree const & lhs, DataTree const & rhs) const{
        return lhs.getName() < rhs.getName();
    }

    bool DataTreeComparitor::operator () (std::string const & lhs, DataTree const & rhs) const{
        return lhs < rhs.getName();
    }

    bool DataTreeComparitor::operator () (DataTree const & lhs, std::string  const & rhs) const{
        return lhs.getName() < rhs;
    }

    DataTree DataTree::getChild(std::string const & name) const{
        return *m_children.find(name); // problem line
    }
}

I cannot for the life of me work out why the compiler isn't using DataTreeComparitor to compare DataTree against an std::string.

My question is, why isn't it doing so? As you can see, I've tried adding operator overloads to the comparitor where std::string is both the left hand operator and the right hand.

Note:

I know there are many essential features things missing from this DataTree type; it is still a work in progress.

OMGtechy
  • 7,935
  • 8
  • 48
  • 83

1 Answers1

2

The problem is that you are calling multiset<DataTree, DataTreeComparitor>::find with an std::string parameter. That cannot work, because it requires a DataTree, and there is no conversion from std::string to DataSet.

You could fix this by adding an implicit converting constructor:

class DataTree{
public:
  DataTree(const std::string& name) : m_name(name) {}
  ....
};
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • Is there no way I can do this through the comparitor? – OMGtechy Aug 03 '14 at 15:24
  • 1
    @OMGtechy No, not in C++11. [C++14 has something that might work for this use case](http://en.wikipedia.org/wiki/C%2B%2B14#Heterogeneous_lookup_in_associative_containers). – juanchopanza Aug 03 '14 at 15:25
  • Thank you! I look forward to C++14 then, and will use your solution in the meantime. I can't imagine I'll be getting such features is `mingw32` for quite some time. – OMGtechy Aug 03 '14 at 15:28