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

时间:2017-04-30 13:21:38

标签: templates visual-c++ c++14 decltype template-deduction

此代码在 g ++(Coliru上编译正常,但 Visual C ++(rextester - 无论是在线还是我的桌面。< / p>

它是更大的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
}
  

&#39; T * AAA :: test(T *)&#39;:无法推断出&#39; T &#39;从   &#39; int TTT3 :: &#39;

问题

  • 为什么?我的代码错了吗? - 我不这么认为。
  • 如何在Visual C ++中编译?我需要它。

2 个答案:

答案 0 :(得分:1)

这对我来说并不合适,因为

中的第一个&d
decltype(AAA::test(&d)) dfd=AAA::test(&d);

是在成员初始值设定项之外隐式使用this。我无法在标准中找到任何例外情况,隐含地使用this decltype内有效,加上所有三个主要编译器都会抱怨,如果您将&d替换为显式{{1} }}

不幸的是,除非您替换&this->d的实际类型或为其创建typedef,否则我不会看到任何简单的方法。

答案 1 :(得分:1)

这是Visual Studio特有的错误。根据标准:

[expr.unary.op/4]

  

指向成员的指针仅在显式&amp;使用和它的   操作数是一个未括在括号中的限定ID。 [ 注意   是,表达式&amp;(qualified-id),其中包含qualified-id   在括号中,不形成“指针”类型的表达式   会员”。也不是qualified-id,因为没有隐含的   从非静态成员函数的qualified-id转换为   键入“指向成员函数的指针”,因为它来自左值   函数类型为“指向函数的指针”([conv.func])。 也不是   &amp; unqualified-id指向成员的指针,即使在范围内也是如此   unqualified-id's class。 - end note]

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

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

Live Example

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