如果我删除类型的复制构造函数和/或复制赋值构造函数
Bar
,
struct Bar {
Bar() = default;
Bar(Bar const&) = delete;
};
std::optional<Bar>
不可复制分配。
using T = std::optional<Bar>;
static_assert(!std::is_copy_assignable_v<T>);
这正是我所期望的。对于
boost::optional<Bar>
来说似乎也是如此,但不幸的是 std::is_copy_assignable_v
的计算结果为 true。
using T = boost::optional<Bar>;
static_assert(std::is_copy_assignable_v<T>); // why doesn't this fail?
因此,以下代码无法编译:
template <typename T>
void foo() {
if constexpr (std::is_copy_assignable_v<T>){
T lhs;
T rhs;
lhs = rhs;
} else {
std::cout<< "Nope!\n";
}
}
int main()
{
foo<std::optional<Bar>>(); // works, prints "Nope!"
foo<boost::optional<Bar>>(); // compiler error
}
GCC 13.2 的编译器错误:
In file included from /opt/compiler-explorer/libs/boost_1_84_0/boost/optional.hpp:15,
from <source>:4:
/opt/compiler-explorer/libs/boost_1_84_0/boost/optional/optional.hpp: In instantiation of 'void boost::optional_detail::optional_base<T>::construct(argument_type) [with T = Bar; argument_type = const Bar&]':
/opt/compiler-explorer/libs/boost_1_84_0/boost/optional/optional.hpp:277:20: required from 'void boost::optional_detail::optional_base<T>::assign(const boost::optional_detail::optional_base<T>&) [with T = Bar]'
/opt/compiler-explorer/libs/boost_1_84_0/boost/optional/optional.hpp:249:19: required from 'boost::optional_detail::optional_base<T>& boost::optional_detail::optional_base<T>::operator=(const boost::optional_detail::optional_base<T>&) [with T = Bar]'
/opt/compiler-explorer/libs/boost_1_84_0/boost/optional/optional.hpp:1099:15: required from 'void foo() [with T = boost::optional<Bar>]'
<source>:34:34: required from here
/opt/compiler-explorer/libs/boost_1_84_0/boost/optional/optional.hpp:410:8: error: use of deleted function 'Bar::Bar(const Bar&)'
410 | ::new (m_storage.address()) unqualified_value_type(val) ;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:19:5: note: declared here
19 | Bar(Bar const&) = delete;
| ^~~
Compiler returned: 1
https://godbolt.org/z/dd3r63KG8
为什么代码不能与
boost::optional
一起使用?
我正在编写一个通用库,它依赖于带有
std::is_assignable_v<T>
的 constexpr-if 块。是否有一种我可以使用或自己编写的替代类型特征,可以可靠地适用于所有类型,包括 boost::optional
?
这是一个悬而未决的问题:https://github.com/boostorg/optional/issues/54
如果类型本身声明它是可复制分配的,则没有其他可以使用的特征。