decltype(*this) - C++0x

S

Stuart Golodetz

Fernando said:
Hi people,

I want to write something like this example ( C++0x )

class comparable
{
public:
bool is_equal( decltype(*this) other ) // should be X&
{
return true; // no matter
}
};


I get the following errors

MSVC10 -> Error 1 error C2355: 'this' : can only be
referenced inside non-static member functions
MinGW (GCC 4.6) -> invalid use of 'this' at top level


In the n1478.pdf paper (
http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1478.pdf ) are examples
that use decltype with "this" keyword, but not as an argument.

class X {
void foo() {
decltype(this) // X*
decltype(*this) // X&
...
}
void bar() const {
decltype(this) // const X*
decltype(*this) // const X&
...
}
};

Sorry for the comparisons, but in the Eiffel language you can write
something like this ...

is_equal (other: like Current) : BOOLEAN


Current is the same that C++ this.
other argument will be the same type as the class where the method is
written.

I wonder whether this alternative decltype (*this) is left out for some
specific reason or if you know any other way to achieve the same result.

Thanks,
Fernando Pelliccioni.

D'oh -- just realised this was cross-posted to the moderated group
(possibly not a good idea, since the posts of anyone who accidentally
replies to both won't come through in comp.lang.c++ until they pass
moderation). For what it's worth, the reply I just sent said:

===

One way of achieving the same result here might be CRTP:

#include <iostream>

class Comparable
{
public:
virtual ~Comparable() {}
virtual bool is_equal(const Comparable& rhs) const = 0;
};

template <typename T>
class TypedComparable : public Comparable
{
public:
bool is_equal(const Comparable& rhs) const
{
const T *p = dynamic_cast<const T*>(&rhs);
if(p) return typed_is_equal(*p);
else return false;
}

virtual bool typed_is_equal(const T& rhs) const = 0;
};

class X : public TypedComparable<X>
{
private:
int m_i;
public:
X(int i)
: m_i(i)
{}
public:
bool typed_is_equal(const X& rhs) const
{
return m_i == rhs.m_i;
}
};

class Y : public TypedComparable<Y>
{
public:
bool typed_is_equal(const Y& rhs) const
{
return true;
}
};

int main()
{
X x1(23), x2(23), x3(9);
Y y;
std::cout << x1.is_equal(x2) << ' ' << x1.is_equal(x3) << ' ' <<
x1.is_equal(y) << ' ' << y.is_equal(y) << '\n';
return 0;
}

Not sure if that helps at all?

Cheers,
Stu
 
F

Fernando

Hi people,

I want to write something like this example ( C++0x )

class comparable
{
public:
bool is_equal( decltype(*this) other ) // should be X&
{
return true; // no matter
}
};


I get the following errors

MSVC10 -> Error 1 error C2355: 'this' : can only be
referenced inside non-static member functions
MinGW (GCC 4.6) -> invalid use of 'this' at top level


In the n1478.pdf paper (
http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1478.pdf ) are examples
that use decltype with "this" keyword, but not as an argument.

class X {
void foo() {
decltype(this) // X*
decltype(*this) // X&
...
}
void bar() const {
decltype(this) // const X*
decltype(*this) // const X&
...
}
};

Sorry for the comparisons, but in the Eiffel language you can write
something like this ...

is_equal (other: like Current) : BOOLEAN


Current is the same that C++ this.
other argument will be the same type as the class where the method is
written.

I wonder whether this alternative decltype (*this) is left out for some
specific reason or if you know any other way to achieve the same result.

Thanks,
Fernando Pelliccioni.
 
L

Luc Danton

Hi people,

I want to write something like this example ( C++0x )

class comparable
{
public:
bool is_equal( decltype(*this) other ) // should be X&
{
return true; // no matter
}
};


I get the following errors

MSVC10 -> Error 1 error C2355: 'this' : can only be
referenced inside non-static member functions
MinGW (GCC 4.6) -> invalid use of 'this' at top level


In the n1478.pdf paper (
http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1478.pdf ) are examples
that use decltype with "this" keyword, but not as an argument.

class X {
void foo() {
decltype(this) // X*
decltype(*this) // X&
...
}
void bar() const {
decltype(this) // const X*
decltype(*this) // const X&
...
}
};

Sorry for the comparisons, but in the Eiffel language you can write
something like this ...

is_equal (other: like Current) : BOOLEAN


Current is the same that C++ this.
other argument will be the same type as the class where the method is
written.

I wonder whether this alternative decltype (*this) is left out for some
specific reason or if you know any other way to achieve the same result.

Thanks,
Fernando Pelliccioni.

I'd like to point out that the examples you provided are not equivalent
to your code: in the examples, decltype(*this) appears in the _body_ of
the function; in your case it appears in the signature. This is not
innocent since things like:

struct T {
void f(T* t = this);
};

are invalid. I don't know the rules exactly are but I think 'this' can
only appear in a method body. So I'm not sure your decltype would work
(I expect it to only work for legal expressions).

Finally, I don't think that decltype(*this) is T&. It may very well be
T. To get T& you can either do decltype((*this)), or perhaps more
clearly: decltype(*this)&.
 
F

Fernando

D'oh -- just realised this was cross-posted to the moderated group
(possibly not a good idea, since the posts of anyone who accidentally
replies to both won't come through in comp.lang.c++ until they pass
moderation). For what it's worth, the reply I just sent said:

===

One way of achieving the same result here might be CRTP:

#include <iostream>

class Comparable
{
public:
     virtual ~Comparable() {}
     virtual bool is_equal(const Comparable& rhs) const = 0;

};

template <typename T>
class TypedComparable : public Comparable
{
public:
     bool is_equal(const Comparable& rhs) const
     {
         const T *p = dynamic_cast<const T*>(&rhs);
         if(p) return typed_is_equal(*p);
         else return false;
     }

     virtual bool typed_is_equal(const T& rhs) const = 0;

};

class X : public TypedComparable<X>
{
private:
     int m_i;
public:
     X(int i)
     :    m_i(i)
     {}
public:
     bool typed_is_equal(const X& rhs) const
     {
         return m_i == rhs.m_i;
     }

};

class Y : public TypedComparable<Y>
{
public:
     bool typed_is_equal(const Y& rhs) const
     {
         return true;
     }

};

int main()
{
     X x1(23), x2(23), x3(9);
     Y y;
     std::cout << x1.is_equal(x2) << ' ' << x1.is_equal(x3) << ' ' <<
x1.is_equal(y) << ' ' << y.is_equal(y) << '\n';
     return 0;

}

Not sure if that helps at all?

Cheers,
Stu

Thanks Stu,

Actually I was referring to the use of decltype(*this) in the
signature of a function.

Regards,
Fernando.
 
S

Stuart Golodetz

<snip -- news server only lets me quote a certain number of lines,
apologies>
Thanks Stu,

Actually I was referring to the use of decltype(*this) in the
signature of a function.

Regards,
Fernando.

I did see that :) Just thought that you were also interested in other
ways of achieving what seemed to be the underlying goal since you said
"if you know any other way to achieve the same result". Guessing the way
I interpreted it wasn't the way you meant it though(!)

Cheers,
Stu
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top