我有以下在Visual Studio 2013和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() {}
(Live sample here on Coliru)
在clang和GCC上编译时,此代码可以正常工作。但是在VS2013上,它失败并显示:
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
由于某种原因,VS编译器试图调用
foo
的副本构造函数,这根本没有任何意义。它完全忽略了构造函数的第二个参数。有趣的是,如果我将
foo
的构造函数调用更改为大括号,如下所示:std::unique_ptr<foo<another>> f{new foo<another>{this, &another::callback}};
它在MSVC上工作正常。谁能解释这种行为?一种方法比另一种更正确吗?这仅仅是MSVC的另一个错误,还是由于某些不受支持的C++ 11功能?
最佳答案
一旦编译器遇到第一个错误,其余的就只是垃圾。忽略它。 (我通常只查看出现的第一个编译器错误,请参阅VC++的here)
在这种情况下,两者完全等效。 MSVC完全无法解析&another::callback
,随后将其忽略以进一步分析该行。
关于c++ - MSVC和Clang之间不一致的大括号或相等初始化行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26241178/