c++visual-studiocompiler-errorsfunction-templates

Function template won't compile in VS2019 express


I have a project with quite a lot of function templates that I wrote back in Visual Studio 2017, and it always worked fine. Now I have to build it in VS2019, because I need to include the lib in another project that is written in VS2019, and the thing won't build.

There is one function template it seems to take issue with, although it doesn't actually complain about the function itself. The compiler just says "identifier not found" when I invoke it in the code. The thing is there in the namespace, however, even intellisense sees it and links to it without complaining. Just the compiler won't.

Here's the code in question:

// declaration

namespace Oparse
{
    // lots of other functions, many of them templates
    template <typename T> OpModel<T> *_ModelPtr(T *receiver) { return new OpModel<T>(receiver); };
}

// Invocation

namespace Oparse
{
        template <class T, class U>
    class OpModelFactory
        : public OpNestable
    {
        public:
        OpModelFactory<T, U>(vector<U*> &receiver) : OpNestable(OP_MODELFACTORY), receiver(receiver) {};
        // other stuff

        void Serialize(string key, stringstream &stream, unsigned int indents)
        {
            for (unsigned int i = 0; i < receiver.size(); ++i)
            {
                // check if the instances are really of the type of this OpModel, otherwise there may be duplicates between polymorphic factories populating the same receiver.
                T *currentModel = dynamic_cast<T*>(receiver[i]);
                if (currentModel != NULL)
                {
                    OpModel<T> *parser = _ModelPtr<T>(currentModel);    // <-- identifier not found
                    parser->Serialize(key, stream, indents);
                    delete parser;
                }
            }
        };

        private:
        vector<U*> &receiver;
    }
}

If I comment that invocation, the project builds, despite there being a whole lot more function templates declared right where this one is. I have no clue what to do to make the linker find it. Are there any Visual Studio wizards who could give me a hint? I must honestly confess that I haven't used the IDE in years, and it's my first time in Visual Studio 2019...

Here's the complete output of the error. There's a second message to it, but I found it perfectly unhelpful:

1>D:\Orbiter_installs\Orbiter2016\Orbitersdk\Oparse\include\OpModel.h(138,27): error C3861: '_ModelPtr': identifier not found
1>D:\Orbiter_installs\Orbiter2016\Orbitersdk\Oparse\include\OpModel.h(152): message : see reference to class template instantiation 'Oparse::OpModelFactory<T,U>' being compiled

And no, there's not further message attached. I have seen similar messages that usually go on with "with ... $further information", but this is all I get.


Solution

  • There is a circular dependency problem.

    In Oparse.h, you first include OpModel.h that requires_ModelPtr in implementation of Serialize , but_ModelPtr is only defined later in the header.

    You need to forward declare the template method.

    In OpModel.h, write this instead:

    namespace Oparse
    {
        template<typename T> class OpModel;
        template <typename T> OpModel<T>* _ModelPtr(T* receiver);
        // Remaining of OpModel.h...
        typedef map<string, pair<Oparse::OpValue*, vector<Oparse::OpValidator*>>> OpModelDef;
        typedef vector<pair<Oparse::OpValue*, vector<Oparse::OpValidator*>>> OpValues;
        ...