c++ - 具有 std::map 和 std::variant 的不完整类型

标签 c++ c++17 libstdc++ incomplete-type

考虑在 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; 
}

由于试图实例化 std::pair<const int, recursive_tag>,因此无法在 gcc 7/8 上编译,它本身就失败了,因为 recursive_tag是不完全类型。

但是,编译器错误调用堆栈中的任何内容都没有告诉我为什么 std::pair<const int, recursive_tag>需要实例化。最上面一行是:

variant:252:48: required from ‘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))); }

在输入 map<int, recursive_tag> 时在那里拼写,实际的map应该实例化的类型是 map<int, RecursiveVariant<int, map<int, recursive_tag>>> ...这应该只需要实例化 pair<const int, RecursiveVariant<...>> .

简单制作recursive_tag完整(即通过添加 {} )解决了问题。但问题的根源是什么?

最佳答案

line at issue来电

std::_Destroy(std::__addressof(__get<_Np>(__v)));

__get 执行 ADL 的需要足以触发 __v 类型的任何和所有关联类的实例化,即 _Variant,以查找在这些类中定义的具有该名称的潜在友元函数(和函数模板)。这包括让你绊倒的pair

关于c++ - 具有 std::map 和 std::variant 的不完整类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50589231/

相关文章:

c++ - Windows 10:Pen(手写笔)在MFC应用程序上不起作用

c++ - 关于QList类型实例的复制构造函数的奇怪问题

c++ - 流式传输 stringstream 是 libstdc++ 扩展吗?

c++ - 与 cuda 相关的 libstdc++.so.6 的链接器问题

c++ - 带线程的 Qt 信号槽

c++ - CMake OpenCL : can't read kernel file

c++ - CRTP 模式不会触发完整模板实例化

c++ - 计算负实数值的 Gamma 函数(C++、Boost)

c++ - 在编译时收集所有静态 C 字符串的地址

windows - Windows 上的 libc++、Clang 和 LLVM