0

I'm making a template class, that requires an std::set, it's working perfectly, until I pass a Compare class with it.

test.h

class test
{
    std::set<T> s;
    public:
        test(std::set<T>&) ;
....
}

test.cpp

std::set<std::string, std::less<std::string> > a;
test<std::string> x(a)

I can't get my head wrapped around how to pass the function and how to use it at test.h.

Edit: The error that I'm getting is

error: no matching function for call to 'test<std::__cxx11::basic_string<char> >::test(std::set<std::__cxx11::basic_string<char>, std::less<std::string>>&)'
test<std::string> x( a );

I tried to make a constructor that ask for a function too but:

test(std::set<T, bool (*f)(T, T)>&);

, then I got another error, that I can't use f as a function

Wooknows
  • 1
  • 1
  • What error are you getting? – Jason May 22 '22 at 08:17
  • 2
    You need a second template parameter `class Compare` so you can use `std::set&` – Goswin von Brederlow May 22 '22 at 08:17
  • Does this answer your question? [Custom comparator via explicit constructor for sorting std::set](https://stackoverflow.com/questions/4425212/custom-comparator-via-explicit-constructor-for-sorting-stdset) – Jason May 22 '22 at 08:35
  • @Goswin von Brederlow I tried this too, but I didn't know what default function should I give if there is no second parameter. – Wooknows May 22 '22 at 08:37
  • 1
    The same `std:set` has – Goswin von Brederlow May 22 '22 at 08:44
  • @Goswin von Brederlow I just did it, I changed all my codes, so do I need now for example two constructor? One with test(std::set, Compare) and one without the Compare test(std::set)? – Wooknows May 22 '22 at 08:57
  • 1
    no, just provide a default parameter for Compare – Goswin von Brederlow May 22 '22 at 08:59
  • @Goswin von Brederlow Now I'm getting this error: C:\Users\User\AppData\Local\Temp\cc9msYlk.o:test.cpp:(.text+0x30e): undefined reference to `test, std::allocator >, std::less, std::allocator > > >::contains(std::__cxx11::basic_string, std::allocator > const&) const' – Wooknows May 22 '22 at 09:23

1 Answers1

0

You can add second template parameter and provide default value (std::less<Key> is default for std::map)

template <class T, class Compare = std::less<T>>
class test
{
    std::set<T, Compare> s;
public:
    test(std::set<T, Compare>&) {};

    template <class It>
    void set_union1(It begin, It end)
    {
        s.insert(begin, end);
    }   

    template <class T2, class Compare2>
    void set_union2(const test<T2, Compare2>& z)
    {
        s.insert(z.begin(), z.end());
    }

    auto begin() { return s.begin(); }
    auto end() { return s.end(); }
    auto begin() const { return s.begin(); }
    auto end() const { return s.end(); }
};

and then use it like this

std::set<std::string> a;
test<std::string> x(a);

std::set<std::string, std::greater<std::string>> b;
test<std::string, std::greater<std::string>> y(b);

std::set<std::string, std::function<bool(const std::string &, const std::string &)>> c([](const std::string &a, const std::string &b){ return a < b; });
test<std::string, std::function<bool(const std::string &, const std::string &)>> z(c);

or since C++17

std::set<std::string> a;
test x(a);

std::set<std::string, std::greater<std::string>> b;
test y(b);

std::set<std::string, std::function<bool(const std::string &, const std::string &)>> c([](const std::string &a, const std::string &b){ return a < b; });
test z(c);

You can implement operations involving sets with different comparators like set_union1 or set_union2 (personally I prefer set_union1) and use them like:

y.set_union1(z.begin(), z.end());
y.set_union2(z);
Antoni
  • 176
  • 2
  • 6
  • Thanks, yeah, now I'm doing like this and everything works, as long as I'm not using different Compare classes. I have a union function that adds element of a new set to the already existing ones, but if the new set doesn't have the Compare class of the existing one, its doesn't work. The error is: no matching function The function looks like this: void set_operations::set_union(const std::set& t); – Wooknows May 22 '22 at 13:17
  • @Wooknows I added an example of how to implement operations mixing sets with different comparators (set_union1 and set_union2). – Antoni May 23 '22 at 08:44