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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With