gpt4 book ai didi

c++ - boost::optional 与 std::optional 对于不可复制的对象

转载 作者:太空狗 更新时间:2023-10-29 22:56:23 25 4
gpt4 key购买 nike

我尝试从 VS2015 更新到 VS2017,但下面的代码在新版本中不起作用。如您所见,定义了一个移动构造函数,它会自动删除复制构造函数。

#include <boost/optional.hpp>
#include <vector>

struct Foo {
Foo() {}
Foo(Foo&& other) {}
};

int main() {
std::vector<boost::optional<Foo>> foos;
foos.resize(42);
return 0;
}

编译错误为

1>...\boost\dist\include\boost-1_66\boost\optional\optional.hpp(384): error C2280: 'Foo::Foo(const Foo &)': attempting to reference a deleted function
1>...\main.cpp(7): note: compiler has generated 'Foo::Foo' here
1>...\boost\dist\include\boost-1_66\boost\optional\optional.hpp(383): note: while compiling class template member function 'void boost::optional_detail::optional_base<T>::construct(const Foo &)'
1> with
1> [
1> T=Foo
1> ]
1>...\boost\dist\include\boost-1_66\boost\optional\optional.hpp(181): note: see reference to function template instantiation 'void boost::optional_detail::optional_base<T>::construct(const Foo &)' being compiled
1> with
1> [
1> T=Foo
1> ]
1>...\boost\dist\include\boost-1_66\boost\optional\optional.hpp(831): note: see reference to class template instantiation 'boost::optional_detail::optional_base<T>' being compiled
1> with
1> [
1> T=Foo
1> ]
1>...\msvc\14.12.25827\include\vector(1902): note: see reference to class template instantiation 'boost::optional<Foo>' being compiled
1>...\msvc\14.12.25827\include\vector(1901): note: while compiling class template member function 'boost::optional<Foo> *std::vector<boost::optional<Foo>,std::allocator<_Ty>>::_Udefault(boost::optional<Foo> *,const unsigned __int64)'
1> with
1> [
1> _Ty=boost::optional<Foo>
1> ]
1>...\msvc\14.12.25827\include\vector(1528): note: see reference to function template instantiation 'boost::optional<Foo> *std::vector<boost::optional<Foo>,std::allocator<_Ty>>::_Udefault(boost::optional<Foo> *,const unsigned __int64)' being compiled
1> with
1> [
1> _Ty=boost::optional<Foo>
1> ]
1>...\main.cpp(10): note: see reference to class template instantiation 'std::vector<boost::optional<Foo>,std::allocator<_Ty>>' being compiled
1> with
1> [
1> _Ty=boost::optional<Foo>
1> ]
1>...\main.cpp(7): note: 'Foo::Foo(const Foo &)': function was implicitly deleted because 'Foo' has a user-defined move constructor

现在有趣的是,当我使用 std::optional 而不是 boost::optional 时它确实可以编译。我不太确定问题出在哪里以及应该怪谁:我、boost、微软、c++ 标准?有谁知道这是怎么回事吗?

这是一个已知问题吗?是 boost 中的错误还是它不起作用是正确的?

最佳答案

这似乎是 STL 实现的问题。

来自最新的草案,n4700:

26.2.1 一般容器要求 [container.requirements.general] 定义DefaultInsertableMoveInsertable , 并且还部分指出:

T is CopyInsertable into X means that, in addition to T being MoveInsertable into X, the following expression is well-formed:

allocator_traits<A>::construct(m, p, v)

and its evaluation causes the following postcondition to hold: The value of v is unchanged and is equivalent to *p.

(在这种情况下,Tboost::optional<Foo>Xstd::vector<T> 。)

很明显,TDefaultInsertableMoveInsertable但不是 CopyInsertable .

26.3.11.3 vector容量 [vector.capacity] 部分说明:

void resize(size_type sz);

Effects: If sz < size(), erases the last size() - sz elements from the sequence. Otherwise, appends sz - size() default-inserted elements to the sequence.

Requires: T shall be MoveInsertable and DefaultInsertable into *this.

Remarks: If an exception is thrown other than by the move constructor of a non-CopyInsertable T there are no effects.

尽管我没有 C++11 或 C++14 的官方拷贝,但基于工作拷贝,C++11 没有“备注:”段落,并且略有不同的“需要:”段落:

Requires: T shall be CopyInsertable into *this.

因此,foos.resize(42)在 C++11 中不是良构的,但在 C++14 中应该是良构的,因为 T 的要求是MoveInsertableDefaultInsertable vector 中得到满足。

我已经确认@patatahooligan's comment添加 noexceptFoo移动构造函数允许代码在 Clang 和 g++ 7.2.0 中编译。但是,除非我误读了标准,否则不要求非 CopyInsertable T的移动构造函数是 noexcept;事实上,该标准似乎允许非 CopyInsertable 的可能性T的移动构造函数可以抛出异常,在这种情况下不能保证是否有效果。

更新 我已提交 GCC 错误 8398183982 .

关于c++ - boost::optional 与 std::optional 对于不可复制的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48340618/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com