Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive variant definition within template class scope gives incomplete type error, why?

I tried to adapt this article to my context where the recursive variant should be defined within the scope of a template class.

Simplifying everything to the extreme, this gives me the following code snippet:

#include <variant>

struct LiteralExpr
{
    int value;
};

template <typename T>
struct BaseSpace
{
    struct AddExpr;
    struct AddExprBox
    {
        const AddExpr &_impl;

    public:
        AddExprBox(const AddExpr &obj) {}
    };
    using Expr = std::variant<AddExprBox, LiteralExpr>;
    struct AddExpr
    {
        std::variant<AddExprBox, LiteralExpr> lhs;
    };
};

auto main() -> int
{
    auto expr = BaseSpace<int>::Expr(LiteralExpr{2});
}

Sadly, this fails to compile on clang with the following error:

main.cpp:22:47: error: field has incomplete type 'std::variant<AddExprBox, LiteralExpr>' std::variant<AddExprBox, LiteralExpr> lhs;

If:

  • I remove the copy constructor within AddExprBox, it compiles;
  • I make Basespace a "non-template" class, it compiles;
  • I explicitly instantiate `BaseSpace, it compiles;

Any idea of why this behavior occurs? And how to fix it?

like image 896
rudolf_markov Avatar asked Feb 18 '26 23:02

rudolf_markov


1 Answers

Any idea of why this behavior occurs?

This seems to be a gcc and clang bug as the program is well-formed. In particular, the error(saying lhs has incomplete type) generated by gcc and clang seems incorrect.

Note also that the program works fine in msvc. MSVC working demo.


And how to fix it?

There is nothing technically wrong with the program.

The gcc bug report is submitted as:

GCC rejects valid program involving std::invariant saying incomplete type

like image 193
Anoop Rana Avatar answered Feb 21 '26 13:02

Anoop Rana



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!