How to get a constant ad?

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(xg())).name()<<std::endl; // Prints "d", not "i" return 0; } 

How to change decltype(std::declval<Derived>().f()) so that it returns int , not double ?

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

+8
c ++ c ++ 11 const decltype
source share
3 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 are making the call is const .

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

+6
source share

You are trying to use Derived in a context where it should be complete, but it still cannot be completed as it is part of the return method type that is required to complete the definition. This loop cannot be solved for the compiler.

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

+5
source share

Throw declval out of the window; when your type expression depends on the parameters of the function, members of the class and / or this , it is almost certainly easier and more clear to put it in the return type of return, where you can refer to them by name:

 struct Derived : public Base { Derived() {} auto g() const -> decltype(f()); }; 

I added the default constructor created by default to Derived to const Derived x; was correctly formed in ยง8.5 / 6.

0
source share

All Articles