13
template<typename T>
struct foo{
    void f(){
        decltype(*this) a(*this);
        do_some_test(a);
    }
    T data;
};
//compiler won't accept this

In my interpretation, decltype should return the a type so that we can use it in declaration. But google says that in decltype(x),if x is a lvalue, it will return T& where T is the type of x.

But what they designed it to return a reference for? Furthermore, what should I do to create a instance of the class that has the same type as *this in a template?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
sqd
  • 1,485
  • 13
  • 23
  • 4
    possible duplicate of [In C++, what expressions yield a reference type when decltype is applied to them?](http://stackoverflow.com/questions/17241614/in-c-what-expressions-yield-a-reference-type-when-decltype-is-applied-to-them) – Fsmv Aug 14 '14 at 15:50
  • There's also this question which talks about how to create a new instance with decltype [Using new with decltype](http://stackoverflow.com/questions/25309356/using-new-with-decltype) – Fsmv Aug 14 '14 at 15:55
  • *"But what they designed it to return a reference for?"* Every expression has a value category (lvalue, xvalue or prvalue). `decltype` reflects that property by applying reference qualifers: an lvalue-reference qualifier for lvalue-expressions, an rvalue-ref for xvalues and no reference for prvalues. – dyp Aug 14 '14 at 16:01
  • Yes,[link](http://stackoverflow.com/questions/25309356/using-new-with-decltype) should be an answer. Apologize for duplication. – sqd Aug 15 '14 at 03:05

1 Answers1

25

decltype deduces the type of expression, unless it is applied to a variable, in which case it deduces the type of that variable:

The type denoted by decltype(e) is defined as follows:

— if e is an unparenthesized id-expression or an unparenthesized class member access, decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;

— otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;

— otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;

— otherwise, decltype(e) is the type of e.

§7.1.6.2 [dcl.type.simple]

Dereferencing a pointer yields an lvalue, and therefore decltype will deduce an lvalue reference to the type of the pointee:

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.

§5.3.1 [expr.unary.op]

Therefore decltype(*p), for some pointer p, deduces an lvalue reference to the type of the pointee.

If you wish to get the type of the pointee from some pointer p, you can use:

std::remove_pointer<decltype(p)>::type

Or:

std::remove_reference<decltype(*p)>::type

Or, in your example, you can simply say foo, type deduction is not required.

Community
  • 1
  • 1