2

The code:

struct Tag {
    std::string left_tag, right_tag;
};

When I try to use this->_tags[__tag] = true;, I got the error:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_base:63:21: error: invalid operands to binary expression ('const Tag' and 'const Tag')
        {return __x < __y;}
                ~~~ ^ ~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/map:1207:17: note: in instantiation of member function 'std::__1::less<Tag>::operator()' requested here
            if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first))
                ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/map:1376:36: note: in instantiation of member function 'std::__1::map<Tag, bool, std::__1::less<Tag>, std::__1::allocator<std::__1::pair<const Tag, bool> > >::__find_equal_key' requested here
    __node_base_pointer& __child = __find_equal_key(__parent, __k);
                                   ^
/Users/xxx/GitHubWorking/MarkupUtils/Syntax.h:69:20: note: in instantiation of member function 'std::__1::map<Tag, bool, std::__1::less<Tag>, std::__1::allocator<std::__1::pair<const Tag, bool> > >::operator[]' requested here
        this->_tags[__tag] = true;
                   ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/utility:419:1: note: candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'const Tag'
operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y)
^
1 error generated.

I am stunned by the series of long stl errors.

According to the most deep error, it is caused by use of const Tag, but there does not seem to be any in my code.

Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
Colliot
  • 1,522
  • 3
  • 16
  • 29

1 Answers1

5

You need to define an operator< for example

struct Tag
{
    std::string left_tag, right_tag;

    bool operator< (const Tag& rhs) const
    {
        return this->left_tag < rhs.left_tag ||
               (this->left_tag == rhs.left_tag && this->right_tag < rhs.right_tag);
    }
};

This will define the less-than operator to sort two Tag instances. As written in the above example, this will sort by preferring left_tag, then right_tag.

Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • or use a functor that does the comparison, and use it in the map constructor. – 911 May 11 '15 at 13:29
  • @sam that is also an option, but if you're going to use this class as the key in a map, you might as well define the operator within the `struct`. – Cory Kramer May 11 '15 at 13:30
  • And what if you can't modify your struct to add the operator overload? (e.g. a struct defined in a private library). In this case you can't use the const qualifier and the error will be still here. – Joe Aspara Nov 07 '16 at 11:26
  • 1
    @JoeAspara If the members of the `struct` are `public`, then you can define a free function that takes two objects and compares them. For the OP's example that would look [like this](http://cpp.sh/82xwr). – Cory Kramer Nov 07 '16 at 12:07