GCC/Clang上的模板错误,但在MSVC上没有错误



我有模板和便携性问题。给定此MVCE:

#include <cstdio>
class C
{
public:
    void go()
    {
        printf("gon");
    }
};
template<typename T>
class A
{
public:
    A(T* pInstance) : m_pInstance(pInstance)
    {
    }
protected:
    T* m_pInstance;
};
template<typename T>
class B : public A<T>
{
    using Base = A<T>;
public:
    B(T* pInstance) : A<T>(pInstance)
    {
    }
    void foo()
    {
        B::m_pInstance->go();
        C* a = nullptr;
        if (a == &B::m_pInstance)
        {
        }
    }
};
int main(int argc, char** argv)
{
    C c;
    B<C> b(&c);
    b.foo();
}

我得到错误:

main.cpp:37:9: error: invalid operands to binary expression ('C *' and 'C *A<C>::*')
                if (a == &B::m_pInstance)
                    ~ ^  ~~~~~~~~~~~~~~~
main.cpp:48:4: note: in instantiation of member function 'B<C>::foo' requested here
        b.foo();
          ^
1 error generated.

但是我不确定为什么要这个?好的,我看到类型有何不同,但是为什么后者是会员引起这个问题?Visual Studio(当然确实具有不同的模板引擎(处理相同的罚款。

&B::m_pInstance是指向数据成员的指针。您要么必须将其更改为

if (a == this->B::m_pInstance)

if (a == B::m_pInstance)

如果要将它们作为指针到会员比较,则必须更改a的类型:

    T* (A<T>::*a) = nullptr;

    C* (A<C>::*a) = nullptr;

MSVC如何处理,我不知道 - 但它肯定是一个错误。

&B::m_pInstance恰好是形成指针到成员的语法。您可以将其放在歧义中,以使您期望使用&(B::m_pInstance)的普通成员访问权限,但这然后揭示了另一个问题:

main.cpp:37:15:错误:不同指针类型的比较('c *'and'c **'(        if(a ==&(b :: m_pinstance((            〜 ^ ~~~~~~~~~~~~~~~~ 

我猜你真正想要的是 if(a == B::m_pInstance)

相关内容

最新更新