Reputation: 26405
I have the following code which I compile on Visual Studio 2013 and Clang:
#include <memory>
template<typename T>
class foo
{
public:
typedef void (T::*CallbackFn)();
foo(T* mem, CallbackFn cb) : m_member(mem), m_cb(cb) {}
private:
T* m_member;
CallbackFn m_cb;
};
class another
{
private:
void callback() {}
public:
std::unique_ptr<foo<another>> f{new foo<another>(this, &another::callback)};
};
int main() {}
When compiled on clang and GCC, this code works fine. However on VS2013 it fails with:
main.cpp(22): error C2276: '&' : illegal operation on bound member function expression
main.cpp(22): error C2664: 'foo<another>::foo(const foo<another> &)' : cannot convert argument 1 from 'another *const ' to 'const foo<another> &'
Reason: cannot convert from 'another *const ' to 'const foo<another>'
No constructor could take the source type, or constructor overload resolution was ambiguous
For some reason, VS compiler is trying to invoke the copy constructor of foo
, which makes no sense at all. It's ignoring the 2nd parameter to the constructor entirely.
Interestingly if I change the constructor invocation of foo
to braces like so:
std::unique_ptr<foo<another>> f{new foo<another>{this, &another::callback}};
It works just fine on MSVC. Can anyone explain this behavior? Is one way more correct than the other? Is this just another MSVC bug or due to some unsupported C++11 feature?
Upvotes: 3
Views: 143
Reputation: 60999
Can anyone explain this behavior?
Once the compiler encounters the first error, the rest is just junk. Ignore it. (I generally only look at the first compiler error that comes up, see here for VC++)
Is one way more correct than the other?
Both are completely equivalent in this context. MSVC simply fails to parse &another::callback
and subsequently ignores it for further analysis of the line.
Upvotes: 1