c++templatesmetaprogrammingdeclval

Understanding declval function a little further


I just learn the declval keyword in c++ and I was wondering why in the following code (std::add_rvalue_reference<Foo>::type).constFunc7() x = 3; is not compiling. Isn't it the same thing as decltype(declvalCustom<Foo>().constFunc7()) y = 3; with the template declaration of declvalCustom?

#include <iostream>
#include <utility>

using namespace std;

struct Foo
{
    int constFunc7() { return 7; }
};

template< class T >
typename std::add_rvalue_reference<T>::type declvalCustom();

std::add_rvalue_reference<Foo> helper();

int main()
{
    // decltype(helper().constFunc7()); // not working
    // (std::add_rvalue_reference<Foo>::type).constFunc7() x = 3; // not working
    decltype(declvalCustom<Foo>().constFunc7()) y = 3; // ok
    decltype(std::declval<Foo>().constFunc7()) z = 3; // ok
    return 0;
}

Solution

  • declval is not a keyword. std::declval is a function template, that can only legally appear in unevaluated contexts. Your declValCustom is also a function template with similar properties.

    std::add_rvalue_reference<Foo>::type is a type, not an expression, so you can't use it as a subexpression.