【问题标题】:function template won't compile in VS2019 express函数模板不会在 VS2019 express 中编译
【发布时间】:2021-10-02 16:18:25
【问题描述】:

我有一个项目,其中包含很多我在 Visual Studio 2017 中写回的函数模板,而且它一直运行良好。现在我必须在VS2019中构建它,因为我需要将lib包含在另一个用VS2019编写的项目中,并且东西不会构建。

一个函数模板似乎存在问题,尽管它实际上并没有抱怨函数本身。当我在代码中调用它时,编译器只会说“找不到标识符”。这个东西在命名空间中,然而,即使是 InteliSense 也能看到它并链接到它而不会抱怨。只是编译器不会。

这是有问题的代码:

// 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;
    }
}

如果我评论该调用,项目就会构建,尽管在这个函数所在的位置声明了更多的函数模板。我不知道该怎么做才能让链接器找到它。是否有任何 Visual Studio 奇才可以给我一个提示?老实说,我已经很多年没有使用过 IDE,而且这是我第一次使用 Visual Studio 2019...

这是错误的完整输出。还有第二条消息,但我发现它完全没有帮助:

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

不,没有附加信息。我看到过类似的消息,通常以“with ... $further information”开头,但这就是我得到的全部信息。

【问题讨论】:

  • 可能不是错误的来源,但以下划线后跟大写字母开头的标识符是为编译器保留的。
  • 在上面扩展(不妨学习所有相关规则):What are the rules about using an underscore in a C++ identifier?.
  • 我还要大胆猜测,怀疑你有一个循环头依赖。
  • 链接器错误代码以大写 L 开头。编译器错误代码以大写 C 开头。我想知道为什么会这样。一些奇怪的任意规则。
  • 你可以做的是将项目复制到一个新的地方,进行完全重建,如果问题仍然存在,开始丢弃代码,并用更简单的代码替换你不能简单地剪切和丢弃的代码,直到您到达minimal reproducible example

标签: c++ visual-studio compiler-errors function-templates


【解决方案1】:

存在循环依赖问题

Oparse.h 中,首先在Serialize 的实现中包含需要_ModelPtrOpModel.h,但_ModelPtr 仅在标头中稍后定义。

您需要转发声明模板方法。

OpModel.h 中,改为这样写:

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;
    ...

【讨论】:

  • 哦哇...只是...哇。太感谢了!当我在 VS 2017 中构建时,这不是问题到底是怎么回事??
  • 小备注:我注意到如果您使用OpStdLibs.h 作为预编译头文件,您的项目构建速度会快大约 3 倍。
猜你喜欢
  • 2018-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多