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?