错误:静态断言失败:模板参数必须是完整的类或无界数组

error: static assertion failed: template argument must be a complete class or an unbounded array

提问人:glades 提问时间:7/28/2022 更新时间:7/28/2022 访问量:1265

问:

我从一个基类派生,我试图在其中定义一个类型。该类型通过变体依赖于自身,因此它需要在定义时知道基类的内存布局。但是,我不是过早地定义类型吗?所以我认为这会起作用,但它没有(CompilerExplorer):

#include <variant>
#include <cstddef>
#include <array>


template <size_t V> struct container_base;
template <size_t V> struct container;

template <size_t V>
using val = std::variant<std::monostate, int, container_base<V>>;

template <size_t V>
struct container_base
{
    using iterator = typename std::array<val<V>, V>::iterator;
};

template <size_t V>
struct container : public container_base<V>
{
};

int main()
{
    container<100> A;
}

这将产生:

In file included from /opt/compiler-explorer/gcc-trunk-20220726/include/c++/13.0.0/variant:37,
                 from <source>:1:
/opt/compiler-explorer/gcc-trunk-20220726/include/c++/13.0.0/type_traits: In instantiation of 'struct std::is_copy_constructible<container_base<100> >':
/opt/compiler-explorer/gcc-trunk-20220726/include/c++/13.0.0/type_traits:3202:33:   required from 'constexpr const bool std::is_copy_constructible_v<container_base<100> >'
/opt/compiler-explorer/gcc-trunk-20220726/include/c++/13.0.0/variant:329:5:   required from 'constexpr const bool std::__detail::__variant::_Traits<std::monostate, int, container_base<100> >::_S_copy_ctor'
/opt/compiler-explorer/gcc-trunk-20220726/include/c++/13.0.0/variant:1334:11:   required from 'class std::variant<std::monostate, int, container_base<100> >'
/opt/compiler-explorer/gcc-trunk-20220726/include/c++/13.0.0/array:109:55:   required from 'struct std::array<std::variant<std::monostate, int, container_base<100> >, 100>'
<source>:15:11:   required from 'struct container_base<100>'
<source>:19:8:   required from 'struct container<100>'
<source>:25:20:   required from here
/opt/compiler-explorer/gcc-trunk-20220726/include/c++/13.0.0/type_traits:1012:52: error: static assertion failed: template argument must be a complete class or an unbounded array
 1012 |       static_assert(std::__is_complete_or_unbounded(__type_identity<_Tp>{}),
      |

我理解它,因此变体在首次使用时需要一个完整的类型才能使用(这是主要的!但是在那之前类型是完整的,所以我不知道为什么它不起作用。我能做些什么来解决这个问题?

C++ 继承 C++17 using-directives 模板实例化

评论

0赞 glades 7/28/2022
I@AlanBirtles我知道成员,但对于类型也是如此吗?毕竟,它们对内存布局没有贡献
1赞 paolo 7/28/2022
typename std::array<val<V>, V>::iterator需要完整。但这不会发生,因为在这一点上,(这取决于)还没有被定义。如果定义 ,则代码将编译。val<V>container_base<V>val<V>container_base<V>::iterator = val<V>*
0赞 glades 7/28/2022
@paolo 谢谢是有道理的。限定访问 (::) 的C++规则是什么?此时限定符是否始终必须是可定义的?
0赞 Igor Tandetnik 7/29/2022
"[res.on.functions]/2具体而言,在以下情况下,影响是不确定的:......(2.5) — 如果在实例化模板组件或评估概念时将不完整类型用作模板参数,除非该组件特别允许。访问需要实例化,这需要实例化,这需要实例化,在这一点上是一个不完整的类型。std::array<val<V>, V>::iteratorstd::array<val<V>, V>val<V>std::variant<std::monostate, int, container_base<V>>container_base<V>

答: 暂无答案