c++ - MSVC 和 Clang 之间不一致的大括号或相等初始化行为

标签 c++ c++11 visual-studio-2013 clang language-lawyer

我在 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 功能?

最佳答案

Can anyone explain this behavior?

一旦编译器遇到第一个错误,剩下的就是垃圾。忽略它。 (我通常只查看出现的第一个编译器错误,对于 VC++,请参见 here)

Is one way more correct than the other?

两者在这个上下文中是完全等价的。 MSVC 根本无法解析 &another::callback 并随后忽略它以进一步分析该行。

关于c++ - MSVC 和 Clang 之间不一致的大括号或相等初始化行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26241178/

相关文章:

c++ - 访问 GL_DEPTH_COMPONENT 纹理

c++ - 为什么 std::shuffle 采用右值引用?

c++ - G++ CAS 的奇怪行为

C++ 条件变量和等待

visual-studio - 生产力电动工具 2013 删除垂直缩进线

c - 为什么 openssl/ssl.h 只包含一个相对路径?

c++ - 使用新的外部函数范围声明和初始化变量

c++ - std::atomic 到什么程度?

c++ - 如何将低级常量应用于模板变量。我正在尝试编写一个 const_cast 实现

javascript - MongoDB 和 Express : Type Error: Converting Circular structure to JSON