Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to use declval in typeid for TDM-GCC

Compiler: TDM-GCC-5.1.0 (SJLJ unwinding)

I was playing around with declval and I noticed that I was unable to use it in a context where it should work: as an argument to typeid().

In the following code, I use declval for one of it's primary use cases: to obtain the return type of a method without going through an instance. The error I get is the static_assert message of declval, but that should be impossible because typeid() doesn't evaluate it's argument in this case:

#include <typeinfo>
#include <utility>

struct Foo
{
    int func();
};

int main()
{
    typeid(std::declval<Foo>().func());
}

This doesn't compile for me (when compiled with -std=c++14). My only guess is that either I've found a compiler bug, or I've done something obviously wrong and I can't see it. If it is the latter, my apologies.

EDIT: Thanks to ildjarn for helping me out, the solution is to use decltype, so the last line of code becomes:

typeid(decltype(std::declval<Foo>().func()));

and this works nicely. However, now my question becomes: how come? Both typeid() and decltype() are unevaluated contexts, so I'm not sure what the difference is.

like image 804
Paul Rich Avatar asked Aug 25 '16 22:08

Paul Rich


1 Answers

It's a compiler bug.

The solution around it is to use decltype() around the expression. Both decltype() and typeid() (in this case of a non-polymorphic-glvalue expression) are unevaluated contexts, which shouldn't make a difference, which is what makes this a bug. Using decltype() here acts as a sort of "unevaluated context buffer", and somehow typeid() likes this better.

Well, time to contact TDM about this. This bug isn't TDM's issue, it's a vanilla bug (thanks ildjarn).

like image 175
Paul Rich Avatar answered Oct 23 '22 11:10

Paul Rich