Trying to better understand std::declval, I came up with the following "toy model" code:
#include <iostream>
#include <typeinfo>
struct Bar
{
Bar(double); // some non-default ctor
double f(); // some function of which return type we want to get
};
using Barref = Bar&&; // emulating std::declval<Bar>()
int main()
{
// FUNKY, compiles in g++, not in clang++
// error: unexpected type name 'Barref': expected expression
decltype(Barref.f()) x; // (1)
std::cout << typeid(x).name() << std::endl; // i -> int INCORRECT
// OK, just for testing
decltype(std::declval<Bar>().f()) y; // (2)
std::cout << typeid(y).name() << std::endl; // d -> double CORRECT
}
So I'm typedef-ing Barref
as a rvalue reference of type Bar&&
, and use it in an a decltype
expression in (1). If I understand correctly, this is exactly what std::declval
does, it is a non-defined function that returns a rvalue reference to its template parameter
template<class T>
typename std::add_rvalue_reference<T>::type declval();
so we can then use the latter in unevaluated contexts, such as decltype
. It is useful whenever the type has a non-default ctor, and we'd like to get some type information about some member function without the need to construct the object. Well, that's what I though my code below does. g++5.1 compiles it, but x
is of type int
(instead of double
, as I would have guessed). However, clang++
fails to compile the code, saying
error: unexpected type name 'Barref': expected expression decltype(Barref.f()) x;
My question(s):
Is the code above legal? Is my usage of
decltype(Barref.f())
really the same as usingdecltype(std::declval<Bar>().f())
? It seems a bit weird, asBarref.f()
is not really a return value of a function (even if un-evaluated). I realized that evendecltype(Bar.f())
compiles (g++), with no type alias whatsoever.If the code is legal, why does the type of
x
isint
instead ofdouble
?
Minimized to
This is plainly invalid code, yet GCC 5.1 and trunk accept it. Not much to say about it other than "bug". Interestingly, both correctly rejects