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

Another problem with std::set

21 views
Skip to first unread message

Joseph Hesse

unread,
Dec 22, 2016, 7:22:27 PM12/22/16
to
In the following example, if I define a set in main() everything
works but if I define it, in the same way, in a struct it doesn't work.

g++ -std=c++11 Set.cpp

Thank you, (especially your patience)
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;
}

struct Y
{
// error, Compiler says Comp is not a type, it is not a type
// it is a function ptr since it is the name of a function
std::set<X, bool (*)(const X &, const X &)> AnotherSetOfX(Comp);
};

int main()
{
// works fine
std::set<X, bool (*)(const X &, const X &)> SetOfX(Comp);
}

Alf P. Steinbach

unread,
Dec 22, 2016, 7:48:09 PM12/22/16
to
There are three ways to initialize a data member of a class type object:

struct S{ int x{42}; };
struct T{ int x = 42; };
struct U{ int x; U():x{42}{} };

The last one defines a default constructor for `U`.

The two first specify a default initialization that can be overridden by
a constructor, and if it's not overridden it is as if it was done by the
constructor like the one in `U`.

• • •

I assume that you're doing this for learning & language exploration.

But for practical programming just do as Mr. Flibble wrote:

define an `operator<` for the class, e.g. like this:

struct Point
{
int x = 0;
int y = 0;

friend
auto operator<( Point const& a, Point const& b )
-> bool
{ return tie( a.x, a. y ) < tie( b.x, b.y ); }
};

… where `tie` is `std::tie` from the `<tuple>` header.

• • •

An alternative to `tie` and that kind of stuff, is to define a
three-valued `compare` function, like `std::string::compare`, and then
inherit from a class template that defines `<` and other relational
operators in terms of `compare`. The inherit-in-an-implementation is
called the Barton-Nackman trick. It's in Wikipedia and other places.

Cheers & hth.,

- Alf

Bo Persson

unread,
Dec 23, 2016, 1:28:02 PM12/23/16
to
On 2016-12-23 01:22, Joseph Hesse wrote:
> In the following example, if I define a set in main() everything
> works but if I define it, in the same way, in a struct it doesn't work.
>
> g++ -std=c++11 Set.cpp
>
> Thank you, (especially your patience)
> 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;
> }
>
> struct Y
> {
> // error, Compiler says Comp is not a type, it is not a type
> // it is a function ptr since it is the name of a function
> std::set<X, bool (*)(const X &, const X &)> AnotherSetOfX(Comp);
> };

If Comp had been a type, AnotherSetOfX(Comp); would have declared a
function taking a Comp parameter and returning a set.

The syntax for member initializations was deliberatly designed so that
it could not be confused with declaring a function. So you can only use
= Comp or {Comp}, but not (Comp).


Bo Persson


0 new messages