Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to obtain a const qualified declval?

Consider the following code:

#include <iostream>
#include <type_traits>
#include <typeinfo>

struct Base
{
    int f() const;
    double f();
};

struct Derived
: public Base
{
    template <typename T = decltype(std::declval<Derived>().f())> // Modify this
    T g() const;
};

int main()
{
    const Derived x;
    std::cout<<typeid(decltype(x.g())).name()<<std::endl; // Prints "d", not "i"
    return 0;
}

How to modify decltype(std::declval<Derived>().f()) so that it will return int and not double?

I've tried decltype(std::declval<const Derived>().f() but it does not compile.

like image 252
Vincent Avatar asked Jan 13 '14 20:01

Vincent


2 Answers

GCC 4.8.1 likes this:

template <typename T = decltype(std::declval<Base const>().f())> 

You need to tell the compiler that the object through which you make the call is const.

You cannot specify Derived here in this declval because at the point of the call, Derived is an incomplete type. In addition, you don't even need Derived as part of the declval since f() is a member of Base.

like image 176
John Dibling Avatar answered Nov 17 '22 04:11

John Dibling


You are trying to use Derived in a context where it required to be complete, but it can't be complete yet as it is part of the method's return type which is required to complete the definition. This loop is impossible to solve for the compiler.

You need to use the base class with std::declval<const Base>() and your code will compile.

like image 43
Daniel Frey Avatar answered Nov 17 '22 05:11

Daniel Frey