C++ C++;.hpp文件中静态函数的链接器错误

C++ C++;.hpp文件中静态函数的链接器错误,c++,function,static,linker,duplicates,C++,Function,Static,Linker,Duplicates,我使用的是一个开源库,它提供了一个.hpp文件,其中定义了几个静态函数,如下所示 当我在我的项目中包含两次这个文件时,我总是会收到一个链接器错误,它会抱怨重复的符号。我很清楚函数被定义了两次,但我不知道如何解决这个问题。我曾尝试将函数标记为外部函数或内联函数,但没有成功 解决这个问题的最佳方法是什么 #ifndef OPENMVG_ROBUST_ESTIMATOR_ACRANSAC_H_ #define OPENMVG_ROBUST_ESTIMATOR_ACRANSAC_H_ #include

我使用的是一个开源库,它提供了一个.hpp文件,其中定义了几个静态函数,如下所示

当我在我的项目中包含两次这个文件时,我总是会收到一个链接器错误,它会抱怨重复的符号。我很清楚函数被定义了两次,但我不知道如何解决这个问题。我曾尝试将函数标记为外部函数或内联函数,但没有成功

解决这个问题的最佳方法是什么

#ifndef OPENMVG_ROBUST_ESTIMATOR_ACRANSAC_H_
#define OPENMVG_ROBUST_ESTIMATOR_ACRANSAC_H_

#include <algorithm>
#include <cmath>
#include <iterator>
#include <vector>
#include <limits>
#include <iostream>

#include "openMVG/robust_estimation/rand_sampling.hpp"

namespace openMVG {
namespace robust{

static double logcombi(size_t k, size_t n)
{...}

...

分辨率:事实证明,我所指的hpp文件包含一个文件,该文件定义了一个与原始文件中某个函数同名的函数,这就是导致链接器错误的原因。我不知道为什么只包含一次.hpp文件时,这一点就起作用了。

我知道你说过你已经这样做了,但是替换了

static double logcombi(size_t k, size_t n)


并完全重新编译。

在标题中分发库是一件非常奇怪的事情。由于您可以访问源代码,我只需创建相应的cpp文件,将代码从标头复制并粘贴到cpp文件,然后删除标头中的函数体

我还将从头文件中删除静态函数:在文件中使用静态(私有)函数来查找可导出符号(即公共函数)实际上没有多大意义

最后,您确定该hpp文件中只有函数吗?如果存在常数,则同样存在问题。在这种情况下,我会在报头中保留带有extern的声明,并将常量移动到cpp文件中

我知道,这是一个很大的工作(嗯,实际上不是很多),但这也是安排事情的唯一明智的方式


希望这有帮助。

据我所知,您可以在声明这些函数的同一位置实现这些函数。这是双重包含错误的原因。到目前为止,您有两种选择:

  • 按照芭丝谢芭的建议使用“内联”子句。问题是:“内联”只是一个提示。编译器可能会拒绝您内联函数的尝试,即使请求“forceinline”。看起来,您的案例不兼容,因为它对您没有帮助
  • 像往常一样拆分一个函数.H+.CPP对,这样客户端代码将包含.H文件,然后链接到包含.CPP的lib

  • 将文件命名为.HPP而不是.H与编译器处理它的方式无关。您可以对文件使用任意扩展名,然后将其作为头包含。因此,命名约定只不过是好的编程风格(对于C/C++兼容的标题,.H. C++的HPP)。

    当询问编译器/链接器错误时,总是在你的问题中包含实际的错误消息。或者,如果它们太多(数百个),那么前几个和最后几个都是相关的。我以前也犯过同样的错误。如果
    静态
    实际上没有什么意义。刚刚删除了,我编辑了我的问题。由于模板功能的原因,这项工作无法完成。请上传整个内容,我明天再看一看。总是可以连接C++代码;最后我非常感谢你!您可以在这里获得hpp文件:(名称为“robust_estimator_ACRansac.hpp”。它包括来自同一目录的另一个文件。)正如我所说,只有当我将该文件包括在至少两个其他文件中时才会出现问题。我发现了问题;请参考我原来的帖子。
    static double logcombi(size_t k, size_t n)
    
    inline double logcombi(size_t k, size_t n)