i am a newbie in c++. the source codes are taken from github.com/srsran/srsRAN. i am trying to call a function from a class nas_5g. this class is inside namespace srsue as shown in the header file below.
header file nas_5g.h
#include "srsue/hdr/stack/upper/nas_5g.h"
namespace srsue {
class nas_5g : public nas_base, public nas_5g_interface_rrc_nr, public nas_5g_interface_procedures
{
public:
explicit nas_5g(srslog::basic_logger& logger_, srsran::task_sched_handle task_sched_);
virtual ~nas_5g();
int init(usim_interface_nas* usim_,
rrc_nr_interface_nas_5g* rrc_nr_,
gw_interface_nas* gw_,
const nas_5g_args_t& cfg_);
void stop();
void run_tti();
bool is_registered();
int get_k_amf(srsran::as_key_t& k_amf);
uint32_t get_ul_nas_count();
int write_pdu(srsran::unique_byte_buffer_t pdu);
int switch_off();
}
source file nas_5g.cc
using namespace srsran;
using namespace srsran::nas_5g;
namespace srsue {
nas_5g::nas_5g(srslog::basic_logger& logger_, srsran::task_sched_handle task_sched_) :
nas_base(logger_, MAC_5G_OFFSET, SEQ_5G_OFFSET, NAS_5G_BEARER),
task_sched(task_sched_),
reregistration_timer(task_sched_.get_unique_timer()),
registration_proc(this),
state(logger_),
pdu_session_establishment_proc(this, logger_)
{
// Configure timers
}
nas_5g::~nas_5g() {}
int nas_5g::switch_off()
{
logger.info("Switching off");
send_deregistration_request_ue_originating(true);
return SRSRAN_SUCCESS;
}
i tried to define the object and call function switch_off() in the main.cc file as shown below
main.cc
#include "srsue/hdr/stack/upper/nas_5g.h"
using namespace srsue;
int main(int argc, char* argv[])
{
srsue::nas_5g nas5g;
nas5g.switch_off();
}
when compiling the source codes, i received below error:-
/srsRAN/srsue/src/main.cc: In function ‘int main(int, char**)’:
/srsRAN/srsue/src/main.cc:823:17: error: no matching function for call to ‘srsue::nas_5g::nas_5g()’
823 | srsue::nas_5g nas5g;
| ^~~~~
In file included from /srsRAN/srsue/src/main.cc:50:
/srsRAN/srsue/hdr/stack/upper/nas_5g.h:59:12: note: candidate: ‘srsue::nas_5g::nas_5g(srslog::basic_logger&, srsran::task_sched_handle)’
59 | explicit nas_5g(srslog::basic_logger& logger_, srsran::task_sched_handle task_sched_);
| ^~~~~~
/srsRAN/srsue/hdr/stack/upper/nas_5g.h:59:12: note: candidate expects 2 arguments, 0 provided
make[2]: *** [srsue/src/CMakeFiles/srsue.dir/build.make:63: srsue/src/CMakeFiles/srsue.dir/main.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:11439: srsue/src/CMakeFiles/srsue.dir/all] Error 2
make: *** [Makefile:163: all] Error 2
appreciate if anyone could shed some light. thanks in advance!
Related
I'm facing this problem when trying to create a builder design-pattern, here is HtmlElement.h header file:
Edit
I included both headers and cpp implementations along with error generated and code causing the error in main.cpp
#ifndef BUILDER_HTMLELEMENT_H
#define BUILDER_HTMLELEMENT_H
#include <string>
#include <vector>
#include "HtmlBuilder.h"
class HtmlElement {
friend class HtmlBuilder;
private:
std::string name;
std::string text;
std::vector<HtmlElement> elements;
const int indent_size{2};
HtmlElement()=default;
HtmlElement(std::string, std::string);
public:
std::string str(int indent=0)const;
static HtmlBuilder build(const std::string &root_name);
};
#endif //BUILDER_HTMLELEMENT_H
And this is the builder class header file:
#ifndef BUILDER_HTMLBUILDER_H
#define BUILDER_HTMLBUILDER_H
#include "HtmlElement.h"
class HtmlBuilder {
private:
HtmlElement root;
public:
HtmlBuilder(const std::string &);
HtmlBuilder &add_child(std::string, std::string);
std::string str()const;
operator HtmlElement()const{return root;}
};
#endif //BUILDER_HTMLBUILDER_H
The implementation for HtmlElement.cpp file:
#include <sstream>
#include "HtmlElement.h"
HtmlElement::HtmlElement(std::string name, std::string text) : name{std::move(name)},
text{std::move(text)} {}
std::string HtmlElement::str(int indent) const {
std::ostringstream oss{};
std::string i{std::string(indent_size * indent, ' ')};
oss << i << "<" << name << ">" << std::endl;
if (!text.empty())
oss << std::string(indent_size * (indent + 1), ' ') << text << std::endl;
for (const auto &element:elements)oss << element.str(indent + 1);
oss << i << "</" << name << ">" << std::endl;
return oss.str();
}
HtmlBuilder HtmlElement::build(const std::string &root_name) {return {root_name};}
And the implementation for HtmlBuilder.cpp file:
#include "HtmlBuilder.h"
HtmlBuilder::HtmlBuilder(const std::string &root_name) { root.name = root_name; }
HtmlBuilder &HtmlBuilder::add_child(std::string name, std::string text) {
HtmlElement e{std::move(name), std::move(text)};
root.elements.emplace_back(e);
return *this;
}
std::string HtmlBuilder::str() const { return root.str(); }
Everything was compiling without any problem (and no issue with HtmlElement data member inside HtmlBuilder class) until I added this static function to the HtmlElement class:
static HtmlBuilder build(const std::string &root_name);
Although HtmlBuilder.h is included, I'm having the error of "HtmlBuilder does not name a type", I tried many solutions like declaring HtmlBuilder class ahead in HtmlElement and/or declaring HtmlElement class ahead in HtmlBuilder (both headers are included in each other's classes).
Could anyone please help why it's happening when I declared a return type on class function(build inside HtmlElement) of another(HtmlBuilder) and what would be the solution?
Please note, the only way I managed to make it work was by putting all classes together in the main.cpp!!
The code in main.cpp which generates the error:
HtmlElement builder2 = HtmlElement::build("ul").add_child("li", "hey")
.add_child("li", "there");
std::cout << builder2.str() << std::endl;
Thanks in advance for your help!
EDIT
This is the generated error code:
Building CXX object CMakeFiles/FluentBuilder.dir/HtmlElement.cpp.o
In file included from /cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/HtmlBuilder.h:5,
from /cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/HtmlBuilder.cpp:1:
/cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/HtmlElement.h:21:12: error: 'HtmlBuilder' does not name a type
21 | static HtmlBuilder build(const std::string &root_name);
| ^~~~~~~~~~~
make[3]: *** [CMakeFiles/FluentBuilder.dir/build.make:89: CMakeFiles/FluentBuilder.dir/HtmlBuilder.cpp.o] Error 1
make[3]: *** Waiting for unfinished jobs....
In file included from /cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/HtmlBuilder.h:5,
from /cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/main.cpp:4:
/cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/HtmlElement.h:21:12: error: 'HtmlBuilder' does not name a type
21 | static HtmlBuilder build(const std::string &root_name);
| ^~~~~~~~~~~
/cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/main.cpp: In function 'int main()':
/cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/main.cpp:58:41: error: 'build' is not a member of 'HtmlElement'
58 | HtmlElement builder2 = HtmlElement::build("ul").add_child("li", "hey")
| ^~~~~
In file included from /cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/HtmlElement.h:7,
from /cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/HtmlElement.cpp:2:
/cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/HtmlBuilder.h:11:5: error: 'HtmlElement' does not name a type
11 | HtmlElement root;
| ^~~~~~~~~~~
/cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/HtmlBuilder.h:16:14: error: expected type-specifier before 'HtmlElement'
16 | operator HtmlElement()const{return root;}
| ^~~~~~~~~~~
make[3]: *** [CMakeFiles/FluentBuilder.dir/build.make:63: CMakeFiles/FluentBuilder.dir/main.cpp.o] Error 1
make[3]: *** [CMakeFiles/FluentBuilder.dir/build.make:76: CMakeFiles/FluentBuilder.dir/HtmlElement.cpp.o] Error 1
make[3]: Leaving directory '/cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/cmake-build-debug'
make[2]: *** [CMakeFiles/Makefile2:76: CMakeFiles/FluentBuilder.dir/all] Error 2
make[2]: Leaving directory '/cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/cmake-build-debug'
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/FluentBuilder.dir/rule] Error 2
make[1]: Leaving directory '/cygdrive/c/CppCourse/DesignPatterns/Builder/FluentBuilder/cmake-build-debug'
make: *** [Makefile:118: FluentBuilder] Error 2
To be able to return a HtmlBuilder object, the code needs the full and complete definition of the class.
The problem is that you have a circular dependency between the HtmlBuilder and HtmlElement classes, so it's not possible to solve by simple #include of the other header file in its own header file.
One possible way to solve it is to define (implement) the build function separately, for example in a source file, where the full and complete definitions of both classes are available.
On another and unrelated note, only converting constructors (constructors taking a single argument) might need to be explicit.
Your two-argument HtmlElement(std::string, std::string) constructor can never be used in an implicit conversion and therefore doesn't have to be marked as explicit.
I am trying to use tf2_ros::Buffer in a simple code. When I put it in the main function, everything works fine. But when put in a class, building error occurs. The code is like this:
#include <ros/ros.h>
#include <tf2_ros/buffer.h>
#include <tf2_ros/transform_listener.h>
#include <geometry_msgs/TransformStamped.h>
#include <geometry_msgs/Twist.h>
class test_class
{
private:
double start;
double duration;
ros::Time start_time;
ros::Time end_time;
std::string robot_name;
tf2_ros::Buffer tf_buffer; // problem line
tf2_ros::TransformListener* tfListener;
geometry_msgs::TransformStamped transformStamped;
public:
std::string space_name;
std::string node_name;
test_class()
{
space_name = ros::this_node::getNamespace();
node_name = ros::this_node::getName();
}
~test_class()
{}
bool initialize(const ros::NodeHandle& n)
{
ROS_INFO("Class auto_mav_flight initialized done!");
return true;
}
void timer_callback(const ros::TimerEvent& event)
{
ROS_INFO("Timer Callback triggered.");
return;
}
};
int main(int argc, char** argv)
{
ros::init(argc, argv, "auto_mav_node");
ros::NodeHandle node;
ROS_WARN("The node is initilized and started.");
test_class amf = test_class();
amf.initialize(node);
ros::Timer timer_1 = node.createTimer(ros::Duration(0.5), &test_class::timer_callback, &amf);
ros::spin();
return EXIT_SUCCESS;
}
and the building error information is:
/home/arkin/ros_code/sandbox/auto_mav_sandbox/src/auto_mav_flight/src/node_main.cpp: In function ‘int main(int, char**)’:
/home/arkin/ros_code/sandbox/auto_mav_sandbox/src/auto_mav_flight/src/node_main.cpp:73:44: error: no matching function for call to ‘test_class::test_class(test_class)’
test_class amf = test_class();
^
/home/arkin/ros_code/sandbox/auto_mav_sandbox/src/auto_mav_flight/src/node_main.cpp:73:44: note: candidates are:
/home/arkin/ros_code/sandbox/auto_mav_sandbox/src/auto_mav_flight/src/node_main.cpp:26:2: note: test_class::test_class()
test_class()
^
/home/arkin/ros_code/sandbox/auto_mav_sandbox/src/auto_mav_flight/src/node_main.cpp:26:2: note: candidate expects 0 arguments, 1 provided
/home/arkin/ros_code/sandbox/auto_mav_sandbox/src/auto_mav_flight/src/node_main.cpp:9:7: note: test_class::test_class(test_class&)
class test_class
^
/home/arkin/ros_code/sandbox/auto_mav_sandbox/src/auto_mav_flight/src/node_main.cpp:9:7: note: no known conversion for argument 1 from ‘test_class’ to ‘test_class&’
make[2]: *** [auto_mav_flight/CMakeFiles/auto_mav_flight_node.dir/src/node_main.cpp.o] Error 1
make[1]: *** [auto_mav_flight/CMakeFiles/auto_mav_flight_node.dir/all] Error 2
make: *** [all] Error 2
I found that if I comment the code line that declare the tf2_ros::buffer:
tf2_ros::Buffer tf_buffer;
the error disappear.
Why the tf2_ros::Buffer can cause problem of class construction even I just declare it as a member of class?
Any help will be appreciated.
Thanks in advance.
From this :
/home/arkin/ros_code/sandbox/auto_mav_sandbox/src/auto_mav_flight/src/node_main.cpp:26:2:
note: candidate expects 0 arguments, 1 provided
/home/arkin/ros_code/sandbox/auto_mav_sandbox/src/auto_mav_flight/src/node_main.cpp:9:7:
note: test_class::test_class(test_class&)
It appears you are calling the copy constructor of test_class (could be hidden in the layer of ROS, by trying to pass test_class as a function arguments or when using containers).
From tf2_ros::Buffer header, it inherits from BufferCore, which contains a boost::mutex(among other things - there could more than 1 non-copyable attribute) which is not copy-constructible. That makes tf2_ros::Buffer not copy-constructible.
Since test_class do not define a copy-constructor and contains a non-copyable attribute, the compiler cannot generate a copy constructor and fails to compile when you try to call a copy constructor.
For reference :
http://en.cppreference.com/w/cpp/language/copy_constructor
Problem solved! Thank you for help.
I'm writing scheduler for my program. I have got 2 classes: task_timepoint and task_period. task_period is a derived class of task_timepoint.
I wrote constructor for task_timepoint, but when I start writing constructor for task_period I've got errors that I can't solve.
scheduler.hpp:
#ifndef SCHEDULER_H
#define SCHEDULER_H
#include "boost/date_time/posix_time/posix_time.hpp"
#include <functional>
#include <chrono>
namespace schelduler{
using namespace schelduler;
using namespace boost::posix_time;
class task_timepoint{
protected:
ptime run_time; //Time at(after) that task_function should run
std::function<void(void)> task_function; //Function that should be run at specified time
public:
task_timepoint(ptime run_time, std::function<void(void)> task_function);
};
class task_period : public task_timepoint{
private:
time_duration run_period;
public:
task_period(time_duration run_period, std::function<void(void)> task_function);
};
}
#endif
scheduler.cpp:
#include "scheduler.hpp"
using namespace schelduler;
using namespace boost::posix_time;
task_timepoint::task_timepoint(ptime run_time, std::function<void(void)> task_function)
{
task_timepoint::run_time = run_time;
task_timepoint::task_function = task_function;
}
task_period::task_period(time_duration run_period, std::function<void(void)> task_function)
{
this->run_period = run_period;
//task_period::task_function = task_function;
}
Errors:
/home/dm3ch/Workspace/Refregiration_Telemetry/Device/src/scheduler.cpp: In constructor ‘schelduler::task_period::task_period(boost::posix_time::time_duration, std::function<void()>)’:
/home/dm3ch/Workspace/Refregiration_Telemetry/Device/src/scheduler.cpp:12:91: error: no matching function for call to ‘schelduler::task_timepoint::task_timepoint()’
task_period::task_period(time_duration run_period, std::function<void(void)> task_function)
^
/home/dm3ch/Workspace/Refregiration_Telemetry/Device/src/scheduler.cpp:12:91: note: candidates are:
/home/dm3ch/Workspace/Refregiration_Telemetry/Device/src/scheduler.cpp:6:1: note: schelduler::task_timepoint::task_timepoint(boost::posix_time::ptime, std::function<void()>)
task_timepoint::task_timepoint(ptime run_time, std::function<void(void)> task_function)
^
/home/dm3ch/Workspace/Refregiration_Telemetry/Device/src/scheduler.cpp:6:1: note: candidate expects 2 arguments, 0 provided
In file included from /home/dm3ch/Workspace/Refregiration_Telemetry/Device/src/scheduler.cpp:1:0:
/home/dm3ch/Workspace/Refregiration_Telemetry/Device/include/scheduler.hpp:12:11: note: schelduler::task_timepoint::task_timepoint(const schelduler::task_timepoint&)
class task_timepoint{
^
/home/dm3ch/Workspace/Refregiration_Telemetry/Device/include/scheduler.hpp:12:11: note: candidate expects 1 argument, 0 provided
/home/dm3ch/Workspace/Refregiration_Telemetry/Device/include/scheduler.hpp:12:11: note: schelduler::task_timepoint::task_timepoint(schelduler::task_timepoint&&)
/home/dm3ch/Workspace/Refregiration_Telemetry/Device/include/scheduler.hpp:12:11: note: candidate expects 1 argument, 0 provided
make[2]: *** [CMakeFiles/Refregiration_Telemetry-Device.dir/src/scheduler.cpp.o] Error 1
make[1]: *** [CMakeFiles/Refregiration_Telemetry-Device.dir/all] Error 2
make: *** [all] Error 2
Sorry for my bad English
Your task_period constructor tries to call the default constructor for the task_timepoint base class. You need to call it explicitly like this:
task_period::task_period(time_duration run_period, std::function<void(void)> task_function)
: task_timepoint{run_period, task_function},
run_period{run_period}
{}
From http://cppcms.com/wikipp/en/page/cppcms_1x_tut_hello_templates#The.controller
I've places below codes on bottom of hello.cpp:
virtual void main(std::string /*url*/)
{
content::message c;
c.text=">>>Hello<<<";
render("message",c);
}
When running g++ hello.cpp my_skin.cpp -o hello -lcppcms -lbooster, got error:
hello.cpp:44:38: error: ‘virtual’ outside class declaration
hello.cpp:44:38: error: ‘::main’ must return ‘int’
hello.cpp:44:14: warning: first argument of ‘int main(std::string)’ should be ‘int’ [-Wmain]
hello.cpp:44:14: warning: ‘int main(std::string)’ takes only zero or two arguments [-Wmain]
hello.cpp: In function ‘int main(std::string)’:
hello.cpp:44:38: error: declaration of C function ‘int main(std::string)’ conflicts with
hello.cpp:27:5: error: previous declaration ‘int main(int, char**)’ here
hello.cpp: In function ‘int main(std::string)’:
hello.cpp:48:23: error: ‘render’ was not declared in this scope
Do I missed something
The error messages are telling you everything you need to know.
virtual can only be used in a class. Your main method is not in a class.
The main method must return an int. Yours is returning void.
You have two main methods, one that is main(std::string) and one that is main(int, char**)
Your render method must have a function prototype above the main method or the entire method needs to me moved.
So this would be more appropriate:
void render(std::string, std::string) // or whatever
{
// do something
}
int main(int argc, char** argv)
{
render("string", c);
return 0;
}
Your hello.cpp should look like below:
#include <cppcms/application.h>
#include <cppcms/applications_pool.h>
#include <cppcms/service.h>
#include <cppcms/http_response.h>
#include <iostream>
#include "content.h"
class hello : public cppcms::application {
public:
hello(cppcms::service &srv) : cppcms::application(srv) {}
virtual void main(std::string url);
};
void hello::main(std::string /*url*/){
content::message cc;
cc.text=">>>Hello<<<";
render("message", cc);
}
int main(int argc,char ** argv){
try {
cppcms::service srv(argc,argv);
srv.applications_pool().mount(cppcms::applications_factory<hello>());
srv.run();
}
catch(std::exception const &e) {
std::cerr<<e.what()<<std::endl;
}
}
I am learning C++ and CppUnit at the same time, using netbeans 7.2.
I create the following file
#include <cstdlib>
using namespace std;
/*
*
*/
class Subtract{
public:
int minus(int a, int b){
return a-b;
}
};
int main(int argc, char** argv) {
return 0;
}
And then I right-click to generate the following cppunit test file
#include "newtestclass.h"
CPPUNIT_TEST_SUITE_REGISTRATION(newtestclass);
newtestclass::newtestclass() {
}
newtestclass::~newtestclass() {
}
void newtestclass::setUp() {
}
void newtestclass::tearDown() {
}
int Subtract::minus(int a, int b);
void newtestclass::testMinus() {
int a=89;
int b=55;
Subtract subtract;
int result = subtract.minus(a, b);
CPPUNIT_ASSERT_EQUAL(34,result);
}
When I try to run the test, it gives the following errors
g++ -c -g -I. -MMD -MP -MF build/Debug/GNU-MacOSX/tests/tests/newtestclass.o.d -o build/Debug/GNU-MacOSX/tests/tests/newtestclass.o tests/newtestclass.cpp
tests/newtestclass.cpp:25: error: 'Subtract' has not been declared
tests/newtestclass.cpp: In member function 'void newtestclass::testMinus()':
tests/newtestclass.cpp:30: error: 'Subtract' was not declared in this scope
tests/newtestclass.cpp:30: error: expected `;' before 'subtract'
tests/newtestclass.cpp:31: error: 'subtract' was not declared in this scope
make[1]: *** [build/Debug/GNU-MacOSX/tests/tests/newtestclass.o] Error 1
make: *** [.build-tests-impl] Error 2
How do I get this to work properly?
In C++, the convention is to declare the classes and functions in a header file (.h file) and implement them in the source file (.cpp file).
Your Subtract.h file (declarations) should have only this:
class Subtract {
public:
int minus(int a, int b);
};
Your Subtract.cpp file (implementation) should have this:
#include "Subtract.h"
int Subtract::minus(int a, int b)
{
return a-b;
}
Then you #include "Subtract.h" in your newtestclass.cpp file.