Reputation: 11934
I am having issues with templates and portability. Given this MVCE:
#include <cstdio>
class C
{
public:
void go()
{
printf("go\n");
}
};
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();
}
I get the error:
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.
But I am not sure why I get this? Ok I see how the types are different but why would the latter being a member cause this problem? Visual Studio (which of course does have a different template engine) handles the same fine.
Upvotes: 0
Views: 157
Reputation: 3911
&B::m_pInstance
is pointer to data member. You either have to change it to
if (a == this->B::m_pInstance)
or
if (a == B::m_pInstance)
If you want to compare them as pointer-to-members you have to change a
's type like:
T* (A<T>::*a) = nullptr;
or
C* (A<C>::*a) = nullptr;
Upvotes: 2
Reputation: 63114
How MSVC handles that, I do not know -- but it sure is a bug.
&B::m_pInstance
happens to be the syntax to form a pointer-to-member. You can disambiguate it to get the plain member access you expect with &(B::m_pInstance)
, but this then reveals another issue:
main.cpp:37:15: error: comparison of distinct pointer types ('C *' and 'C **') if (a == &(B::m_pInstance)) ~ ^ ~~~~~~~~~~~~~~~~~
I guess what you really want is if(a == B::m_pInstance)
.
Upvotes: 0