std::variant of std::string inside any class in constexpr context 编译失败
std::variant of std::string inside any class in constexpr context fails to compile
如下代码
#include <optional>
#include <string>
#include <variant>
constexpr bool USE_VARIANT = 1;
using T = std::conditional_t<USE_VARIANT, std::variant<std::string>, std::string>;
struct S
{
T t;
};
constexpr int func()
{
S s{"str"};
return 0;
}
constexpr int x = func();
int main()
{
}
无法使用 GCC 主干 (compiler explorer link) 编译,消息为
In file included from <source>:4:
<source>:21:23: in 'constexpr' expansion of 'func()'
<source>:19:1: in 'constexpr' expansion of '(& s)->S::~S()'
<source>:10:8: in 'constexpr' expansion of '((S*)this)->S::t.std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~variant()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:1408:28: in 'constexpr' expansion of '((std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Variant_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~_Variant_base()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:736:12: in 'constexpr' expansion of '((std::__detail::__variant::_Variant_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::__detail::__variant::_Variant_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Move_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~_Move_assign_base()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:682:12: in 'constexpr' expansion of '((std::__detail::__variant::_Move_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::__detail::__variant::_Move_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Copy_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~_Copy_assign_base()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:630:12: in 'constexpr' expansion of '((std::__detail::__variant::_Copy_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::__detail::__variant::_Copy_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Move_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~_Move_ctor_base()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:592:12: in 'constexpr' expansion of '((std::__detail::__variant::_Move_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::__detail::__variant::_Move_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Copy_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~_Copy_ctor_base()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:555:12: in 'constexpr' expansion of '((std::__detail::__variant::_Copy_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::__detail::__variant::_Copy_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Variant_storage<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~_Variant_storage()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:481:17: in 'constexpr' expansion of '((std::__detail::__variant::_Variant_storage<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::__detail::__variant::_Variant_storage<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::_M_reset()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:471:23: in 'constexpr' expansion of 'std::__do_visit<void, __detail::__variant::_Variant_storage<false, __cxx11::basic_string<char, char_traits<char>, allocator<char> > >::_M_reset()::<lambda(auto:11&&)>, variant<__cxx11::basic_string<char, char_traits<char>, allocator<char> > >&>(<lambda closure object>std::__detail::__variant::_Variant_storage<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::_M_reset()::<lambda(auto:11&&)>(), (* & std::__variant_cast<__cxx11::basic_string<char, char_traits<char>, allocator<char> >, __detail::__variant::_Variant_storage<false, __cxx11::basic_string<char, char_traits<char>, allocator<char> > >&>((*(std::__detail::__variant::_Variant_storage<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this))))'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:1782:26: in 'constexpr' expansion of '(& __v0)->std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::index()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:555:12: error: accessing value of 's.S::t.std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Variant_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Move_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Copy_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Move_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Copy_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>' through a 'const std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >' glvalue in a constant expression
555 | struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
| ^~~~~~~~~~~~~~~
C++ 错误通常难以理解,但这个错误让我一头雾水。
如果我使用 USE_VARIANT = 0
,它会编译。
如果我把它改成
constexpr int func()
{
T t{"str"};
return 0;
}
它使用任一值编译。
有
constexpr int func()
{
std::optional<T> t{"str"};
return 0;
}
它也不编译。
所以看起来当std::variant<..., std::string, ...>
在class中实例化时,编译失败。 std::vector<char>
而不是 std::string
也会发生同样的情况,但其他 classes(不动态分配内存)似乎工作正常。
我是不是遗漏了什么或者发现了 compiler/stdlib 错误?
错误已 fixed,示例现在可以编译。
如下代码
#include <optional>
#include <string>
#include <variant>
constexpr bool USE_VARIANT = 1;
using T = std::conditional_t<USE_VARIANT, std::variant<std::string>, std::string>;
struct S
{
T t;
};
constexpr int func()
{
S s{"str"};
return 0;
}
constexpr int x = func();
int main()
{
}
无法使用 GCC 主干 (compiler explorer link) 编译,消息为
In file included from <source>:4:
<source>:21:23: in 'constexpr' expansion of 'func()'
<source>:19:1: in 'constexpr' expansion of '(& s)->S::~S()'
<source>:10:8: in 'constexpr' expansion of '((S*)this)->S::t.std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~variant()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:1408:28: in 'constexpr' expansion of '((std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Variant_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~_Variant_base()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:736:12: in 'constexpr' expansion of '((std::__detail::__variant::_Variant_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::__detail::__variant::_Variant_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Move_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~_Move_assign_base()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:682:12: in 'constexpr' expansion of '((std::__detail::__variant::_Move_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::__detail::__variant::_Move_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Copy_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~_Copy_assign_base()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:630:12: in 'constexpr' expansion of '((std::__detail::__variant::_Copy_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::__detail::__variant::_Copy_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Move_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~_Move_ctor_base()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:592:12: in 'constexpr' expansion of '((std::__detail::__variant::_Move_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::__detail::__variant::_Move_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Copy_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~_Copy_ctor_base()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:555:12: in 'constexpr' expansion of '((std::__detail::__variant::_Copy_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::__detail::__variant::_Copy_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Variant_storage<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~_Variant_storage()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:481:17: in 'constexpr' expansion of '((std::__detail::__variant::_Variant_storage<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->std::__detail::__variant::_Variant_storage<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::_M_reset()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:471:23: in 'constexpr' expansion of 'std::__do_visit<void, __detail::__variant::_Variant_storage<false, __cxx11::basic_string<char, char_traits<char>, allocator<char> > >::_M_reset()::<lambda(auto:11&&)>, variant<__cxx11::basic_string<char, char_traits<char>, allocator<char> > >&>(<lambda closure object>std::__detail::__variant::_Variant_storage<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::_M_reset()::<lambda(auto:11&&)>(), (* & std::__variant_cast<__cxx11::basic_string<char, char_traits<char>, allocator<char> >, __detail::__variant::_Variant_storage<false, __cxx11::basic_string<char, char_traits<char>, allocator<char> > >&>((*(std::__detail::__variant::_Variant_storage<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this))))'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:1782:26: in 'constexpr' expansion of '(& __v0)->std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::index()'
/opt/compiler-explorer/gcc-trunk-20211231/include/c++/12.0.0/variant:555:12: error: accessing value of 's.S::t.std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Variant_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Move_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Copy_assign_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Move_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>.std::__detail::__variant::_Copy_ctor_base<false, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::<anonymous>' through a 'const std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >' glvalue in a constant expression
555 | struct _Copy_ctor_base : _Variant_storage_alias<_Types...>
| ^~~~~~~~~~~~~~~
C++ 错误通常难以理解,但这个错误让我一头雾水。
如果我使用 USE_VARIANT = 0
,它会编译。
如果我把它改成
constexpr int func()
{
T t{"str"};
return 0;
}
它使用任一值编译。
有
constexpr int func()
{
std::optional<T> t{"str"};
return 0;
}
它也不编译。
所以看起来当std::variant<..., std::string, ...>
在class中实例化时,编译失败。 std::vector<char>
而不是 std::string
也会发生同样的情况,但其他 classes(不动态分配内存)似乎工作正常。
我是不是遗漏了什么或者发现了 compiler/stdlib 错误?
错误已 fixed,示例现在可以编译。