1

I was studying about the differences between auto and decltype type specifier and I saw in another question that when I use decltype with a reference, like this:

const int ci = 0, &cj = ci;
decltype(ci) x = 0;
decltype(cj) y = x; 

decltype(cj) will not give me the type of the object that cj refers to (that is, const int) but will give me the type of cj itself. So y will be const int&.

Why does this happen? And it could affect my code in someway? Is it related to the difference between decltype() and decltype(())?

Niall
  • 30,036
  • 10
  • 99
  • 142
Gabriel
  • 763
  • 1
  • 10
  • 28
  • 2
    `decltype` gives you the *declared type* of the object, which in this case is `const int&`. – David G Aug 29 '15 at 17:52
  • 1
    It happens because that's what `decltype` was designed to do. We already have `auto` to ignore the reference. – chris Aug 29 '15 at 17:56
  • @chris so basically, decltype should be used to deal with references and auto not? – Gabriel Aug 29 '15 at 18:02
  • I guess it should be noted that `decltype` has other uses like determining which type to use as a return type (which couldn't be left out in C++11), and there are times when you need to grab a type without a new variable. But as `decltype` vs. `auto` for declaring variables like this, that would be the main difference. Of course `decltype` also allows you to use a different initialization method instead of just copying. `decltype` really isn't something that's too common in user code, though. More generic library code. – chris Aug 29 '15 at 18:08
  • @chris that was an awesome explanation and it helped me a lot in terms of understanding when/why to use decltype. Thank you for that! And when I ask about decltype() and decltype(()), is there something related with reference? – Gabriel Aug 29 '15 at 18:26
  • @GabrielMello, That's explained [here](http://stackoverflow.com/questions/3097779/decltype-and-parentheses). – chris Aug 29 '15 at 18:35
  • @chris Thank you so much for the help! – Gabriel Aug 29 '15 at 18:52

2 Answers2

4

The rules of decltype are fairly straightforward (especially when compared to lots of other rules in C++...). For an expression e, decltype(e) is (from [dcl.type.simple], paraphrasing):

  • if e is an unparenthesized id-expression, then the type of e. Exactly the type of e. We're not dropping cv-qualifiers or references or anything. decltype(ci) is const int because that is the type of ci. Likewise, decltype(cj) is const int&.
  • If e is an xvalue, then T&& where T is the type of e.
  • If e is an lvalue, then T& where T is the type of e.
  • Else, the type of e.

We go in order through those bullet points. Where the parentheses makes a difference is when we do decltype((ci)) - (ci) is not an unparenthesized id-expression anymore, so we don't simply take the type of ci. Instead, it's just an lvalue - so we take the type of the expression (const int) and add a reference to it. Hence, decltype((ci)) is const int&. decltype((cj)) is still const int&.

Barry
  • 286,269
  • 29
  • 621
  • 977
2

Why is it double const&? Well, that is the type of the variable.

Is it related to decltype(())? Yes, no, not really, the rules for the two are subtly different, but should both be understood if you are planning on using them.


decltype and auto are very useful additions to C++, a sound understanding of their meaning and use is very useful especially if they are being used in the code. In client type code, auto will probably be much more common.

What is decltype()?

decltype offers a mechanism to get to the type given a variable or expression. It generally features in more generic code, most likely when templates are involved.

What is auto?

auto is effectively a way to say "I don't care for the name of the type (it may be too long), but I want a variable of that type", for e.g. the indexer in a for loop. Note; there are differences between auto, auto& and auto&&; they are well documented here on SO and elsewhere (such as cppreference.com).

Niall
  • 30,036
  • 10
  • 99
  • 142
  • 1
    Very organized explanation and I liked how you goes straight to the point. Thank you for that. – Gabriel Aug 29 '15 at 20:01