【问题标题】:Accessing elements in namespace defined in header file访问头文件中定义的命名空间中的元素
【发布时间】:2020-05-15 07:58:38
【问题描述】:

我正在尝试访问在头文件的命名空间中定义的变量和函数。但是,我收到错误消息:xor.cpp:(.text+0x35): undefined reference to "the function in header file" collect2: error: ld returned 1 exit status。看了这个post,在我看来编译步骤没问题,也因为我可以访问这个头文件中的变量,但是调用函数返回上面提到的错误。我的问题是:如何从我的 main.cpp 访问命名空间中的这些函数?我做错了什么?

类的情况我很清楚,但这里我不明白,因为我不应该创建一个对象,所以只调用前面的命名空间应该可以(?)。

编辑

在 Maestro 建议的更改之后,我已按照以下方式更新了代码,但它仍然无法正常工作。我得到的错误是一样的。如果我定义 using NEAT::trait_param_mut_prob = 6.7; 我得到错误:xor.cpp:127:36: error: expected primary-expression before ‘=’ token

主要 c++

#include "experiments.h"
#include "neat.h"
#include <cstring>

int main(){

  const char *the_string = "test.ne";
  bool bool_disp = true;
  NEAT::trait_param_mut_prob;
  trait_param_mut_prob = 6.7;
  NEAT::load_neat_params(the_string ,bool_disp);
  std::cout << NEAT::trait_param_mut_prob << std::endl;
  return 0;
}

neat.h

    #ifndef _NERO_NEAT_H_
    #define _NERO_NEAT_H_
    
    #include <cstdlib>
    #include <cstring>
    
    namespace NEAT {
        extern double trait_param_mut_prob;
        bool load_neat_params(const char *filename, bool output = false); //defined HERE 
    
    }
    #endif

neat.cpp

#include "neat.h"
#include <fstream>
#include <cmath>
#include <cstring>

double NEAT::trait_param_mut_prob = 0;

bool NEAT::load_neat_params(const char *filename, bool output) { 
                    //prints some stuff
                    return false;
                    };

生成文件

neat.o: neat.cpp neat.h
        g++ -c neat.cpp

【问题讨论】:

  • 标题中的#endif 在哪里?
  • 这并没有解决问题,但是以下划线开头后跟大写字母 (_NERO_NEAT_H_) 的名称和包含两个连续下划线的名称保留供实现使用。不要在你的代码中使用它们。
  • @Maestro 确实我忘了复制帖子中的#endif,但它在代码中
  • @PeteBecker 谢谢你的评论。我在这里实际上要做的是修改我下载的包,所以那些 NERO_NEAT_H 没有问题
  • @Joachim — 下载文件并不能免除它的规则。该标识符保留供实现使用。

标签: c++ function makefile namespaces header-files


【解决方案1】:

您违反了“ODR 规则”(单一定义规则):您在源文件 neat.cpp 中定义了两次 trait_param_mut_probload_neat_params,在 main.cpp 中定义了第二次,因此只需从main.cpp:

//double NEAT::trait_param_mut_prob; //NEAT is the namespace 
//bool NEAT::load_neat_params(const char* filename, bool output); //function defined in the namespace 
  • 在标题中添加#endif neat.h
  • 要使您的函数和变量在 main 中可用,只需使用 using 或完全限定调用,因为正如我所见,您打算在 main 中重新声明它们以避免完全限定它们:在 main 中:

    int main()
    {
    
        using NEAT::trait_param_mut_prob;
        using NEAT::load_neat_params;
    
        const char* the_string = "test.ne";
        bool bool_disp = true;
        trait_param_mut_prob = 6.7;//works perfectly 
        load_neat_params(the_string, bool_disp);
        // or fully-qualify:
    
        //NEAT::load_neat_params(the_string, bool_disp);
        //NEAT::trait_param_mut_prob = 6.7;//works perfectly 
    }
    
  • 你的函数load_neat_params 不返回bool 值也是错误的。所以让它要么返回true要么false

【讨论】:

  • 还是不行。我已经尝试了这两种选择。无论是完全合格还是使用,我仍然得到同样的错误:g++ xor.cpp /tmp/cccl2MH9.o: In function main: xor.cpp:(.text+0x23): undefined reference to NEAT::trait_param_mut_prob' xor.cpp:(.text+0x35): undefined reference to NEAT::load_neat_params(char const*, bool) xor.cpp:(.text+0x3c): undefined reference to NEAT::trait_param_mut_prob' collect2: error: ld returned 1 exit status 。我会更新代码
  • 其实只能通过以下方式调用:using NEAT::trait_param_mut_prob = 6.7我得到xor.cpp:127:36: error: expected primary-expression before ‘=’ token,我还是不明白为什么
  • 不!删除分配:= 6.7,使其变为:using NEAT::trait_param_mut_prob;
  • 请原谅这个愚蠢的问题,但是将源添加到项目中究竟是什么意思?它是用 Ubuntu 18.04 编译的
  • 从终端试试这个:g++ neat.cpp main.cpp -o prog.
猜你喜欢
  • 2018-01-06
  • 1970-01-01
  • 1970-01-01
  • 2013-10-28
  • 1970-01-01
  • 2012-10-03
  • 2010-11-04
  • 1970-01-01
相关资源
最近更新 更多