繁体   English   中英

C++ 中带有 const 参数的 std::variant

[英]std::variant with const arguments in C++

关于与const成员建立联合,有一个很好的未回答的问题: 您能否为具有 const 成员的联合编写一个复制构造函数?

建议之一是改用std::variant 实际上,必须支持 const 类型P0086 - Variant design review 相关段落说:

variant<int, const int>一个variant可以处理const类型:它们只能通过variant构造和emplace()来设置。

所以我认为variant复制构造也必须支持它们。

但是尝试使用此选项:

#include <string>
#include <variant>

using S = std::variant<const int, const std::string>;

int main() {
    S s(1);
    S u = s;

    S v("abc");
    S w = v;
}

在 GCC 中失败并出现一个很长的错误(这里只引用它的开头):

n file included from <source>:2:
/opt/compiler-explorer/gcc-trunk-20211024/include/c++/12.0.0/variant: In instantiation of 'constexpr std::__detail::__variant::_Variadic_union<_First, _Rest ...>::_Variadic_union(std::in_place_index_t<_Np>, _Args&& ...) [with long unsigned int _Np = 1; _Args = {const int&}; _First = const std::__cxx11::basic_string<char>; _Rest = {}]':
/opt/compiler-explorer/gcc-trunk-20211024/include/c++/12.0.0/variant:409:4:   required from 'constexpr std::__detail::__variant::_Variadic_union<_First, _Rest ...>::_Variadic_union(std::in_place_index_t<_Np>, _Args&& ...) [with long unsigned int _Np = 2; _Args = {const int&}; _First = const int; _Rest = {const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >}]'
/opt/compiler-explorer/gcc-trunk-20211024/include/c++/12.0.0/bits/stl_construct.h:119:7:   required from 'constexpr void std::_Construct(_Tp*, _Args&& ...) [with _Tp = std::__detail::__variant::_Variadic_union<const int, const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >; _Args = {const std::in_place_index_t<2>&, const int&}]'

演示: https : //gcc.godbolt.org/z/ocajj3aao

我的代码有问题,还是 GCC 必须接受它?

正如上面的评论中所指出的,在我实施P2231R1之后,该代码最近才开始被 GCC 主干拒绝(并且被所有发布的 GCC 版本接受)。

正如我在错误报告中所说的那样,在 P2231R1 之前,libstdc++ std::variant在构建联合的活动成员时有点快而松。 在 P2231 更改后,我们需要构造正确的联合成员,否则它在constexpr函数中将无效。 这需要进行一些重构才能在构造成员时使用该成员的索引。

现在已经修复,感谢您注意到这个错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM