Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem with std::set

46 views
Skip to first unread message

Joseph Hesse

unread,
Dec 22, 2016, 5:03:38 PM12/22/16
to
The documentation of std::set says that the second optional argument of
a template set instantion should be a function object or a function pointer.
In the example below I am trying to create a set object using a function
pointer.
I compiled the code with:
$ g++ -std=c++11 Set.cpp
and got the compiler error that there was a type mismatch in the second
argument.
Please help.
Thank you,
Joe

========================= Set.cpp =============================
#include <iostream>
#include <set>

class X
{
private:
int x;
public:
X(int a) : x(a) {}
friend bool Comp(const X &, const X &);
};

bool Comp(const X &xobj1, const X &xobj2)
{
return xobj1.x < xobj2.x;
}

int main()
{
std::set<X, Comp> SetOfX; // <== use function pointer

return 0;
}

Alf P. Steinbach

unread,
Dec 22, 2016, 5:25:44 PM12/22/16
to
The second template argument needs to be a /type/.

You could use `decltype(&Comp)` if you feel unsure about function types.

When you do this, using a simple freestanding function, you need to pass
it as a constructor argument. That's because a raw function pointer type
doesn't say anything about which function it is. While a class type does
say all there is to know: it's that class' operator().


Cheers!,

- Alf

Joseph Hesse

unread,
Dec 22, 2016, 6:16:40 PM12/22/16
to
Thank you. I should have known that when instantiating a template, the
stuff that goes between < and > have to be types.
std::set<X, bool (*)(const X &, const X &)> SetOfX(Comp);
fixes it when I want to use function pointers.

Mr Flibble

unread,
Dec 22, 2016, 6:22:24 PM12/22/16
to
Just add an operator< to your class and forget about the template parameter.

/Flibble

Jorgen Grahn

unread,
Jan 6, 2017, 5:19:40 AM1/6/17
to
On Thu, 2016-12-22, Joseph Hesse wrote:
> The documentation of std::set says that the second optional argument of
> a template set instantion should be a function object or a function pointer.
> In the example below I am trying to create a set object using a function
> pointer.
> I compiled the code with:
> $ g++ -std=c++11 Set.cpp

You may want to add some or all of '-Wall -Wextra -pedantic' to that
command line.

> and got the compiler error that there was a type mismatch in the second
> argument.
> Please help.
> Thank you,
> Joe
>
> ========================= Set.cpp =============================
> #include <iostream>
> #include <set>
>
> class X
> {
> private:
> int x;
> public:
> X(int a) : x(a) {}
> friend bool Comp(const X &, const X &);
> };
>
> bool Comp(const X &xobj1, const X &xobj2)
> {
> return xobj1.x < xobj2.x;
> }
>
> int main()
> {
> std::set<X, Comp> SetOfX; // <== use function pointer
>
> return 0;
> }

It's not what you ask for, but I find the simplest thing is to,
whenever possible:

std::set<X> SetOfX;

and define operator< for X.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

jonkalb

unread,
Jan 7, 2017, 11:37:48 AM1/7/17
to
On Thursday, December 22, 2016 at 3:16:40 PM UTC-8, Joseph Hesse wrote:

> Thank you. I should have known that when instantiating a template, the
> stuff that goes between < and > have to be types.
> std::set<X, bool (*)(const X &, const X &)> SetOfX(Comp);
> fixes it when I want to use function pointers.

But, in general, you shouldn't want to use function pointers. In-lineable function objects will give you better performance without giving up clarity.

Jon
0 new messages