Bar*_*rry 14 c++ libstdc++ incomplete-type c++17
考虑这种简化且非常具体的递归变体实现std::variant:
#include <map>
#include <variant>
struct recursive_tag;
template <typename...>
struct RecursiveVariant;
template <>
struct RecursiveVariant<int, std::map<int, recursive_tag>>
: std::variant<int, std::map<int, RecursiveVariant<int, std::map<int, recursive_tag>>>>
{
using underlying = std::variant<int,
std::map<int, RecursiveVariant<int, std::map<int, recursive_tag>>>>;
using underlying::underlying;
};
int main() {
RecursiveVariant<int, std::map<int, recursive_tag>> rv;
}
Run Code Online (Sandbox Code Playgroud)
由于尝试实例化std::pair<const int, recursive_tag>而无法在gcc 7/8上编译,因为它recursive_tag是一个不完整的类型,它本身也会失败.
但是,编译器错误call-stack中没有任何内容向我指出为什么 std::pair<const int, recursive_tag>需要实例化.最重要的是:
变体:252:48:'
void std::__detail::__variant::__erased_dtor(_Variant&&) [with _Variant = const std::__detail::__variant::_Variant_storage<false, int, std::map<int, RecursiveVariant<int, std::map<int, recursive_tag, std::less<int>, std::allocator<std::pair<const int, recursive_tag> > > >, std::less<int>, std::allocator<std::pair<const int, RecursiveVariant<int, std::map<int, recursive_tag, std::less<int>, std::allocator<std::pair<const int, recursive_tag> > > > > > > >&; long unsigned int _Np = 0]' 需要' '
指向:
249 template<typename _Variant, size_t _Np>
250 void
251 __erased_dtor(_Variant&& __v)
252 { std::_Destroy(std::__addressof(__get<_Np>(__v))); }
Run Code Online (Sandbox Code Playgroud)
虽然类型map<int, recursive_tag>拼写在那里,但map应该实例化的实际类型是map<int, RecursiveVariant<int, map<int, recursive_tag>>>......这应该只需要实例化pair<const int, RecursiveVariant<...>>.
简单地recursive_tag完成(即通过添加{})修复问题.但是什么导致问题开始?
T.C*_*.C. 14
std::_Destroy(std::__addressof(__get<_Np>(__v)));
Run Code Online (Sandbox Code Playgroud)
执行ADL的需要__get足以触发该类型的任何和所有相关类的实例化__v,即,_Variant寻找具有在这些类中定义的该名称的潜在朋友函数(和函数模板).那包括pair绊倒了你.
| 归档时间: |
|
| 查看次数: |
596 次 |
| 最近记录: |