Forward declaration in global module fragment
16:14 05 Nov 2025

I have a template class Monomial and a template class Polynomial. Polynomial owns a std::map, double. I would like to create a member function of Monomial which returns a Polynomial. To avoid the circular dependency I attempted the following:

Monomial.ixx

export module Polynomial:Monomial;

template class Polynomial;

export template class Monomial
{
public:
    Polynomial getPolynomial() const;
};

Polynomial.ixx

export module Polynomial:Polynomial;

import :Monomial;

export template class Polynomial
{
private:
    std::map, double> terms;
};

MonomialToPolynomial.ixx

export module Polynomial:MonomialToPolynomial;

import :Polynomial;
import :Monomial;

template Polynomial Monomial::getPolynomial() const
{
    return Polynomial({ { *this, 1.0 } });
}

PolynomialModule.ixx

export module Polynomial;

export import :Polynomial;
export import :Monomial;
export import :MonomialToPolynomial;

However this does not work. If I try to actually use the function as:

import Polynomial;

Monomial<2> m = Monomial<2>();
Polynomial<2> p = m.toPolynomial();

Compiling this on Visual Studio 2022 (MSVC) I get the error error C2027: use of undefined type 'Polynomial<2>. Why does this not work? I have found a workaround, but I'm not sure if it is valid. I write Monomial.ixx as:

module;

template class Polynomial;

export module Polynomial:Monomial;

export template class Monomial
{
public:
    Polynomial getPolynomial() const;
};

template Polynomial Monomial::getPolynomial() const
{
    return Polynomial({ { *this, 1.0 } });
}

Here I forward declared Polynomial in the global module fragment of Monomial.ixx, and defined the function in this file too. Polynomial.ixx remains the same and MonomialToPolynomial with its corresponding module partition are no longer needed. This compiles and all works correctly. Why does this work? Doing this gives me the warning warning C5202: a global module fragment can only contain preprocessor directives. Is this a valid solution? Is there an alternative way of formulating this without needing the forward declaration in the global module fragment.

c++ c++20