为什么这不能在Visual Studio C ++中编译?我正在使用Visual Studio 2017 15.7.1。它用clang和g ++编译:
#include <utility>
#include <vector>
struct Foo {
Foo(int x) {}
Foo(Foo const& b) {}
};
struct Bar {
template <class... Args>
Bar(Args&&... args)
: foo(std::forward<Args>(args)...) {}
Foo foo;
};
void test() {
std::vector<Bar> v;
v.emplace_back(123);
}
错误为error C2664: 'Foo::Foo(const Foo &)': cannot convert argument 1 from 'Bar' to 'int'
请参阅https://godbolt.org/g/bKb34v
编辑:我在此处提交了此问题:https://developercommunity.visualstudio.com/content/problem/252470/perfect-forwarding-compiler-bug.html
答案 0 :(得分:5)
这是你的错误,而不是MSVC的。
Foo
的复制构造函数不是noexcept
,它没有移动构造函数。Bar
隐式声明的移动构造函数也不是noexcept
,因为它需要为Foo
数据成员调用前面提到的复制构造函数。emplace_back
可能会重新分配,并且由于Bar
似乎是可复制的,因此重新分配将复制现有元素以保留强大的异常安全保证。const
或非const
Bar
左值进行此复制。Bar
左值的复制。修复是约束构造函数模板,以便它不会被劫持。例如:
template <class... Args,
class = std::enable_if_t<std::is_constructible_v<Foo, Args...>>>
Bar(Args&&... args)
: foo(std::forward<Args>(args)...) {}