Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 仅标题类+;仅当返回该类的对象时对函数的未定义引用_C++_Gcc_Cmake_Linker_Undefined Reference - Fatal编程技术网

C++ 仅标题类+;仅当返回该类的对象时对函数的未定义引用

C++ 仅标题类+;仅当返回该类的对象时对函数的未定义引用,c++,gcc,cmake,linker,undefined-reference,C++,Gcc,Cmake,Linker,Undefined Reference,我对GCC 5.4.0链接器有一个非常奇怪的问题。我有以下文件: ,, utils.h/cpp, main.cpp spline.h是仅用于将点拟合到样条曲线的标题实用程序类 1) 我使用utils.cpp和CMake创建了一个库: add_library(utils_lib utils.cpp) utils.h是#包括ingspline.h 2) 我从main.cpp创建二进制文件: add_executable(hello_world main.cpp) target_link_libra

我对GCC 5.4.0链接器有一个非常奇怪的问题。我有以下文件:

,,
utils.h/cpp
main.cpp

spline.h
是仅用于将点拟合到样条曲线的标题实用程序类

1) 我使用utils.cpp和CMake创建了一个库:

add_library(utils_lib utils.cpp)
utils.h
#包括
ing
spline.h

2) 我从
main.cpp
创建二进制文件:

add_executable(hello_world main.cpp)
target_link_libraries(hello_world utils_lib)
auto my_spline = fitSpline(x,y);
3) 在
utils.cpp
中,我有以下功能:

tk::spline fitSpline(const std::vector<double>& x,
                     const std::vector<double>& y)
{
    tk::spline output;
    output.set_points(x,y);
    return output;
}
然后我得到这个链接器错误:

undefined reference to `fitSpline(std::vector<double, std::allocator<double> > const&, std::vector<double, std::allocator<double> > const&)'
那我就不会再收到链接器错误了!它编译得很好。我真的不明白问题是什么,有什么提示吗


谢谢

有两个翻译单元。TU用于
utils_lib
和TU用于
main.cpp

未命名名称空间中的名称都位于唯一的名称空间中,并且实际上具有内部链接(因为C++11将它们定义为具有内部链接)

因此,由于有效的内部链接,尝试从不同的TU引用类似于
tk::spline
的类型将失败

如果对象是无状态且不共享的,那么重复使用
spline.h
通常是可以的。但在这里,你没有这样做。通过在一个TU中创建一个对象并尝试通过另一个TU中的类型存储它们,将它们视为可替换的。这将失败,因为它们具有不同的唯一命名空间名称

如果您确实不想在仅标头的库中导出不必要的符号,则应仅为这些符号使用内部“详细信息”命名空间,而将用户应该知道的符号保留在外部命名空间中


顺便说一句,这些都与
cmake
或任何构建系统无关。但是,由于您的问题使用
cmake
使结构更加清晰(顺便说一句,做得好),标记可能很好。

utils.h
中是否存在
fitspeline
的函数签名?我现在唯一能想到的就是。如果可能,在
utils.*
main.cpp
@hnefat中发布相关代码是的,签名在那里。正如我所说的,如果我只是更改返回值类型,一切都会正常工作。我刚刚意识到,
spline.h
的所有内容都在匿名名称空间中,这肯定是原因所在!我是否需要将它包含在每个cpp文件中?如果它们确实在一个文件中,那么文件之外的任何东西都不能访问它们。通过签名,我的意思是问您是否有一个拆分的函数定义和实现,并且忘记了更新其中的一个。在
main.cpp
中包含
spline.h
可能会有所帮助,但我真的不明白为什么会这样。发布更多代码会有所帮助。是的,它们在
utils.cpp
utils.h
中具有相同的签名。我刚刚尝试了
#在
main.cpp
utils.cpp
utils.h
中的所有地方都包含
ing
spline.h
,但仍然不起作用。只有当我跳过
utils
,并在
main.cpp
中直接使用
spline.h
而不是将其包装到函数中时,它才有效。实际上
spline.h
仅以://unnamed名称空间开始,因为实现在这个//头文件中,我们不想将符号导出到obj文件名称空间{namespace tk{(很抱歉格式化,我可以在注释部分编写正确的代码吗?)
double fitSpline(const std::vector<double>& x,
                 const std::vector<double>& y)
{
    tk::spline output;
    output.set_points(x,y);

    return 0.0;
}