首页 > 解决方案 > 对显式实例化的模板函数的未定义引用

问题描述

我有一个带有模板方法的类,该方法在标头中声明并在 cpp 文件中定义,所以

// A.h - declaration
struct A
{
    template<typename T = int> void fun();
};

接着

// A.cpp - definition
#include <iostream>
#include "A.h"

template<typename T> void A::fun()
{
    std::cout << "Hello world template" << std::endl;
}

// Explicit instantiation
template void A::fun<int>();

现在,在其他地方,在测试中,我有

#include "A.h"

int main ()
{
    A a;
    a.fun();
}

并且由于我明确地实例化了int模板参数的函数,所以一切都很好。或者应该是!

我的代码与 GCC 7.3.0 链接良好,但无法与 clang 6 链接,后者报告了对 function 的未定义引用fun

这里发生了什么?还有什么需要我注意的吗?也许是 GCC 认为理所当然而 clang 没有的东西?

谢谢!

编辑

@WhozCraig、@Neil Butterworth 这里是两个工具链的链接命令。

海合会:

/usr/bin/g++  -g   CMakeFiles/test_generator.dir/generator/generator.cpp.o CMakeFiles/test_generator.dir/test_utils.cpp.o  -o test_generator -Wl,-rpath,/home/mleoni/PhD/ABI/libcellml/build/src:/home/mleoni/PhD/ABI/libcellml/build/tests/gtest ../src/libcellmld.so.0.1.0 gtest/libgtest_main.so /usr/lib/x86_64-linux-gnu/libxml2.so gtest/libgtest.so -lpthread

铛:

/usr/bin/clang++  -g   CMakeFiles/test_generator.dir/generator/generator.cpp.o CMakeFiles/test_generator.dir/test_utils.cpp.o  -o test_generator -Wl,-rpath,/home/mleoni/PhD/ABI/libcellml/build/src:/home/mleoni/PhD/ABI/libcellml/build/tests/gtest ../src/libcellmld.so.0.1.0 gtest/libgtest_main.so /usr/lib/x86_64-linux-gnu/libxml2.so gtest/libgtest.so -lpthread

@IdeaHat:不幸的是,这并没有解决问题,我仍然遇到同样的错误

编辑 2 由于我实际尝试编译的代码 [显然] 不是那个,所以我尝试编译这个 MWE,GCC 和 clang 都用cc A.cpp main.cpp.

我现在正试图了解这个最小案例和我实际拥有的代码之间的区别。

标签: c++templatesg++clang++explicit-instantiation

解决方案


我找到了。在这个代码库的某个地方,我不熟悉默认情况下所有类都标记为私有 [如在 Windows D:] 中,并且在我标记我的类之后,公共 clang 最终可以正确链接。

现在情节变厚了,因为使用 clang 编译的二进制文件,我在测试套件中看到了很多使用 GCC 编译时不存在的段错误。

另外,现在我有与这个线程中的问题相同的问题,除了现在 GCC 和 clang 工作正常,而 MSVC 说unresolved external symbol:'( 。


推荐阅读