This code compiles OK on g++ (Coliru), but not Visual C++ (rextester) - both online and my desktop.
It is a simplified version of a much larger Visual Studio 2015 project.
class AAA{
public: template<class T> static T* test(T* hqi){
return hqi;
}
};
class TTT3{
public: int d; //In real case, it is some class, but same error nonetheless.
decltype(AAA::test(&d)) dfd=AAA::test(&d); //<-- error only Visual C++
};
int main(){
int b;
decltype(AAA::test(&b)) dfd=AAA::test(&b); //OK for boths
}
'T *AAA::test(T *)': could not deduce template argument for 'T ' from 'int TTT3:: '
Question
This is a Visual Studio specific bug. According to the standard:
[expr.unary.op/4]
A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses. [ Note: That is, the expression &(qualified-id), where the qualified-id is enclosed in parentheses, does not form an expression of type “pointer to member”. Neither does qualified-id, because there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to member function” as there is from an lvalue of function type to the type “pointer to function” ([conv.func]). Nor is &unqualified-id a pointer to member, even within the scope of the unqualified-id's class. — end note ]
The text in bold is what VC++ doesn't do properly inside decltype for whatever reason. Since hoping that Microsoft will fix it is a fools hope, another workaround you can do is to add the following overload:
template<class C, typename T>
static T* test(T C::*);
Live Example
Possibly in a #ifdef/#endif
block that checks for VC++. Not defining it prevents it being picked silently outside of an unevaluated context such as a decltype, albeit with only a link time error.
This doesn't look valid to me because the first &d
in
decltype(AAA::test(&d)) dfd=AAA::test(&d);
is an implicit use of this
outside of the member initializer. I can't find any exception in the Standard making an implicit use of this
inside decltype
valid, plus all three major compilers complain if you replace the &d
with explicit &this->d
.
Unfortunately, I don't see any easy way around this, unless you substitute the actual type of d
or make a typedef for it.
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