无法从类型x转换为类型x?

时间:2011-12-23 15:31:24

标签: c++ visual-studio function-pointers

编译时(Microsoft Visual C ++ 2005 Express)这段代码:

struct A
{
    template< typename T > static A Foo( void ) { return A(); }
    struct S
    {
        template< typename T > static S GetInstance( void )
        {
            S Result;
            Result.m_funcFoo = &A::Foo< T >;
            return Result;
        }
        A ( *m_funcFoo )( void );
    };
};

int main(int argc, char* argv[])
{
    A::S::GetInstance< int >();
}

我收到了C2440错误:

  

'=':无法从'A(__ cdecl *)(void)'转换为'A(__ cdecl *)(void)'

这对我没有意义。错误文本中指定的两种类型显然是相同的。 此外,将Foo的返回值更改为int时,不会出现此类错误。

这是一个错误还是我做错了什么?

编辑: 所以,如果它是一个错误,有谁知道如何解决这个问题?也许通过使用演员阵容?我需要这段代码来编译......

4 个答案:

答案 0 :(得分:4)

这是一个编译错误。 VC ++正在做一些非常奇怪的事情。

例如,这会生成一个非常不同的错误消息:

struct A
{
    template< typename T > static struct A Foo( void ) { return A(); }
    struct S
    {
        template< typename T > static S GetInstance( void )
        {
            S Result;
            Result.m_funcFoo = &A::Foo< T >;
            return Result;
        }
        A ( *m_funcFoo )( void );
    };
};

sourceFile.cpp(5) : error C3856: 'A::Foo': class is not a class template

这有效:

struct X {};

struct A
{
    template< typename T > static X Foo( void ) { return X(); }
    struct S
    {
        template< typename T > static S GetInstance( void )
        {
            S Result;
            Result.m_funcFoo = &A::Foo< T >;
            return Result;
        }
        X ( *m_funcFoo )( void );
    };
};

显然它被名称A搞糊涂了,它应该引用基类。

添加typedef没有帮助,struct A的前瞻性声明也没有帮助,也没有将名称限定为::Astruct A

奇怪的是,VC ++ 7编译得很好。

解决方法:像这样更改:

struct A
{
    template< typename T > static A Foo( void ) { return A(); }

    struct S;
};

struct A::S
{
    template< typename T > static S GetInstance( void )
    {
        S Result;
        Result.m_funcFoo = &A::Foo< T >;
        return Result;
    }
    A ( *m_funcFoo )( void );
};

反转结果,现在VC ++ 8编译正常,VC ++ 7生成相同的错误消息。

我认为完成后不完整类型和相同类型之间存在类型标识问题。

所有测试均使用Dinkumware Multi-Compiler Test Tool

运行

答案 1 :(得分:1)

我不确定它是否是编译器错误,但至少它记录在msdn上。
我手头没有2005编译器,但如果像这样编写代码,vs2010会编译你的代码:

struct A
{
    template< typename T > static A Foo( void ) { return A(); }
    struct S
    {
        A ( *m_funcFoo )( void );       

        template< typename T > static S GetInstance( void );
    };
};

template< typename T > 
A::S A::S::GetInstance( void )
{
    S Result;
    Result.m_funcFoo = &A::Foo< T >;
    return Result;
}

答案 2 :(得分:1)

看起来像一个错误 - 它在Comeau上编译得很好(http://www.comeaucomputing.com/tryitout)。

答案 3 :(得分:0)

我试图追踪问题,现在似乎甚至没有必要使用模板化函数或嵌套结构来产生这个奇怪的错误。

struct A
{
    typedef A ( * SimpleFuncPtr )( void );
    static void Foo( void )
    {
        SimpleFuncPtr func1 = 0;        // Ok.
        SimpleFuncPtr func2 = func1;    // Ok.
        A ( * func3 )( void ) = func1;  // C2440 on both VS2005 and VS2010
    }
};

通过查看上面的代码,很明显它确实是一个编译器错误(在我看来)。