gpt4 book ai didi

c++ - 如何使用从dll中显式实例化模板派生的dllexport-ed类,而不会发出警告?

转载 作者:行者123 更新时间:2023-12-02 10:35:05 26 4
gpt4 key购买 nike

因此,我有一个dll,可导出从显式实例化(也已导出)的模板派生的类。

parent.hpp

#pragma once
template <typename T>
struct parent {
parent(T t) m_t(t) {};
void print();
T m_t;
};

parent.cpp

template<typename T>
void parent<T>::print() {
cout << m_t << endl;
}
template class LIB_API parent<int>;

child.hpp

#include "parent.hpp"
extern template class parent<int>;
struct LIB_API child : public parent<int> {
using parent<int>::parent;
void some_method();
}

child.cpp 定义 some_method
到目前为止,一切都很好并且可以正常工作。我可以从与dll链接的目标中安全地使用子类。当我在另一个编译单元的dll中使用 child类时,就会出现问题:

some_other_dll_file.cpp :
void func()
{
child c(53);
c.print();
c.some_method();
}

在这种情况下,我会收到警告: warning C4661: 'void parent<int>::print(void)': no suitable definition provided for explicit template instantiation request
(或者在我的特殊情况下,对于使用子类的dll中每个文件的模板头中看不到的每个方法都发出大量警告)

请注意,这只是警告。最终,所有内容都可以编译和链接,并且可以正常工作。

有没有办法更改代码,所以我不会收到此警告?

最佳答案

该代码包含许多错误,可能是一些错误,其他一些则丢失了代码部分,依此类推。

您得到的警告是因为显式实例化的模板(parent<int>)在some_other_dll_file转换单元中没有定义(仅声明)打印方法。检查[SO]: warning C4661:no suitable definition provided for explicit template instantiation request (@SergeBallesta's answer)。您可以通过在parent.hpp中移动打印的正文来摆脱警告。

下面是一个工作示例。

  • Dll项目

    dll00.h:

    #pragma once

    #if defined (DLL00_INTERNAL) || defined(DLL00_STATIC)
    # define DLL00_API
    #else
    # if defined(DLL00_EXPORTS)
    # define DLL00_API __declspec(dllexport)
    # else
    # define DLL00_API __declspec(dllimport)
    # endif
    #endif

    parent.hpp:

    #pragma once
    #include <dll00.h>
    #include <iostream>


    template <typename T>
    class parent {

    public:
    parent(T t): m_t(t) {};
    void print();

    private:
    T m_t;
    };


    template <typename T>
    void parent<T>::print() {
    std::cout << m_t << std::endl;
    }

    parent.cpp:

    #define DLL00_EXPORTS
    #include <parent.hpp>


    template class DLL00_API parent<int>;

    child.hpp:

    #pragma once
    #include <dll00.h>
    #include <parent.hpp>


    extern template class parent<int>;

    class DLL00_API child : public parent<int> {

    public:
    using parent<int>::parent;

    void some_method();
    };

    child.cpp:

    #define DLL00_EXPORTS
    #include <child.hpp>
    #include <iostream>


    void child::some_method() {
    std::cout << "child::some_method" << std::endl;
    }

    other.cpp:

    #define DLL00_INTERNAL
    #include <child.hpp>


    void func() {
    //*
    child c(53);
    c.print();
    c.some_method();
    //*/
    }
  • App项目

    main.cpp:

    #include <child.hpp>

    int main() {
    child c(12);
    c.print();
    c.some_method();

    return 0;
    }

  • 如果出于某种原因,您希望在parent.cpp中包含函数主体,则只需忽略警告。如果您不想看到它,请在parent.hpp的开头添加 #pragma warning(disable: 4661)。但是请记住,在某些情况下忽略警告可能会给您带来麻烦。

    关于c++ - 如何使用从dll中显式实例化模板派生的dllexport-ed类,而不会发出警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60691534/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com