MSVC和Clang之间的不一致的括号或等号初始化行为

3
我有以下代码,我在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() {}

(这里是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功能?


2
这只是一个 MSVC 的 bug。 - Jonathan Wakely
1
它忽略了第二个参数,因为在解析 &another::callback 时出现了错误。 - T.C.
1
代码在最新版本的VC++ http://webcompiler.cloudapp.net/上运行良好。 - user515430
1个回答

1

有人能解释这种行为吗?

一旦编译器遇到第一个错误,其余的都是垃圾。忽略它。(通常我只看第一个编译器错误,参见这里查看VC++的详细信息)

哪个方法更正确?

在这种情况下,两种方法完全等效。MSVC无法解析&another::callback,因此会忽略该行的进一步分析。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接