Home > Enterprise >  Use of incomplete template types in templates
Use of incomplete template types in templates

Time:12-26

This is follow up to a question I asked a few weeks ago in which the answer was that it is ill-formed, no diagnostic required, to use a type in a template that is only complete at the time of the template's instantiation but not at the time of its definition.

My follow up question is is this still true in the case in which the incomplete type is itself dependent on the template parameter? because it seems that it is not. The following compiles in all the compilers on Godbolt, even though foo::do_stuff() is using foo_wrapper::value() given only a forward declaration that a class template foo_wrapper will eventually exist.

#include <iostream>

template<typename T>
class foo_wrapper;

template<typename T>
class foo {
    foo_wrapper<T>& parent_;
public:
    foo(foo_wrapper<T>& wrapped) : parent_(wrapped)
    {}

    void do_stuff() {
        std::cout << "do stuff " << parent_.value() << "\n";
    }
};

template<typename T>
class foo_wrapper {
    foo<T> foo_;
    T value_;
public:

    foo_wrapper(T n) :
        foo_(*this),
        value_(n)
    {}

    void do_stuff() {
        foo_.do_stuff();
    }

    T value() const {
        return value_;
    }

};

int main()
{
    foo_wrapper<int> fw(42);
    fw.do_stuff();
}

CodePudding user response:

This is legal.

The rule of thumb is that everything that depends on template parameters is checked when the template is instantiated. Everything else is either checked when the template is first seen, or when it's instantiated (e.g. MSVC tends to check everything late, and Clang tends to do it as early as possible).

  • Related