模板 – 无法从FieldType *推断出T *的模板参数(仅限Visual C)

此代码在g( Coliru)上编译好,但在Visual C( rextester)上编译 – 在线和我的桌面.

它是更大的Visual Studio 2015项目的简化版本.

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::

>为什么?我的代码错了吗? – 我不这么认为.
>如何在Visual C中编译?我需要它.

最佳答案 这是Visual Studio特定的错误.根据标准:

[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 ]

粗体文本无论出于何种原因,VC在decltype中都没有正确执行.既然希望微软能够修复它是一个愚蠢的希望,你可以做的另一个解决方法是添加以下重载:

template<class C, typename T>
static T* test(T C::*);

Live Example

可能在#ifdef / #endif块中检查VC.不定义它可以防止它在未评估的上下文(例如decltype)之外被静默选取,尽管只有链接时间错误.

点赞