When I try to compile the following code:
#include <iostream>
#include <set>
#include <vector>
using namespace std;
template <class T, class S>
class Property
{
public:
pair<T,S> p;
Property(T t, S s) { p = make_pair(t,s);}
};
int main()
{
set< Property<string, string> > properties;
Property<string, string> name("name", "Andy");
properties.insert(name);
}
I get the compilation error. However, when I replace set by vector and hence use the the push_back function instead of insert function everything works fine. Could anyone explain me what am I doing wrong? Thanks in advice.
In order to insert something into
std::set
, you need to haveoperator<
defined.For example this compiles fine on GCC 4.7.2:
An alternative would be to use
std::unordered_set
though that would require you to provide a hash for the key and definingoperator==
.std::set
stores its values in a sorted binary tree, so it needs to know how to compare the values it holds. By default it usesstd::less
as a comparison function, which for un-specialized user defined types tries to calloperator<
. So, the easiest way to tell the set how to compare your objects is to define anoperator<
for your class:However, there are also other ways of telling
std::set
how to compare your type. One is to specialize thestd::less
template for your class:Another is to replace the default comparison type with a function with the correct signature, or a class that has an
operator()
defined with the correct signature. This is where things start to get ugly.Keep in mind that whatever less-than function you use, that function must define a strict weak ordering for your type.