I have a c++ project with several classes, which all require rng. For this purpose I use the following bit of code, in a header that all classes include.
Random.h :
#include <random>
#include <functional>
std::default_random_engine generator;
std::uniform_real_distribution<float> Udistribution(0.0f, 1.0f);
std::normal_distribution<float> Ndistribution(0.0, 1.0);
auto uniform01 = std::bind(Udistribution, generator);
auto normal01 = std::bind(Ndistribution, generator);
A.h :
#include "Random.h"
...
B.h :
#include "Random.h"
...
But it throws a bunch of linker error on compilation. I have tried to use the extern keyword, but the std::bind messes things up: I can't use auto anymore, and I have to figure out the types of uniform01 and normal01. I came up with the following, which triggers intellisense error : incompatible declarations.
new A.h:
#include "Random.h"
extern std::_Binder<std::_Unforced, const std::uniform_real_distribution<float>&, const std::default_random_engine&> uniform01;
extern std::_Binder<std::_Unforced, const std::normal_distribution<float>&, const std::default_random_engine&> normal01;
Replacing uniform01 with uniform01() does not change anything. Does anyone know what the extern declaration should look like ?
Related
Short context: I am trying to make a Node working on ROS for a TIAGo robot (https://pal-robotics.com/robots/tiago/). It has a working tutorial node on adjusting its head, which works, but I'd now like to make a customized version of that.
I have neatly separated .cpp and .h files of both my node and the tutorial node. Now, I'd like to borrow some functions and definitions from that tutorial node to make my node work. When I build my ROS workspace using catkin, it yields errors concerning 'undefined reference'. I suspect it might be due to the ways I import headers. Some include headers coincide, and I do not know how to handle 'nested' dependencies. Here's what I mean (I've renamed the nodes to my_node and tutorial_node here for simplicity):
my_node.h
#ifndef MY_NODE_H
#define MY_NODE_H
// Declare included packages
#include <ros/ros.h>
#include <math.h>
#include <geometry_msgs/PointStamped.h>
#include <tutorial_node/tutorial_node.h>
// Declare TIAGo's centered viewpoint as a stamped point
geometry_msgs::PointStamped tiagoCenterView;
// Function declarations
geometry_msgs::PointStamped calculateDesiredPoint(geometry_msgs::PointStamped faceCenter);
int calculateCenterDistance(geometry_msgs::PointStamped point_a, geometry_msgs::PointStamped point_b);
void faceCallback(geometry_msgs::PointStamped msg);
#endif
my_node.cpp
#include "my_node/my_node.h"
{actual code content}
tutorial_node.h
#ifndef TUTORIAL_NODE_H
#define TUTORIAL_NODE_H
// C++ standard headers
#include <exception>
#include <string>
// Boost headers
#include <boost/shared_ptr.hpp>
// ROS headers
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <actionlib/client/simple_action_client.h>
#include <sensor_msgs/CameraInfo.h>
#include <geometry_msgs/PointStamped.h>
#include <control_msgs/PointHeadAction.h>
#include <sensor_msgs/image_encodings.h>
#include <ros/topic.h>
// OpenCV headers
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static const std::string windowName = "Inside of TIAGo's head";
static const std::string cameraFrame = "/xtion_rgb_optical_frame";
static const std::string imageTopic = "/xtion/rgb/image_raw";
static const std::string cameraInfoTopic = "/xtion/rgb/camera_info";
// Intrinsic parameters of the camera
cv::Mat cameraIntrinsics;
// Our Action interface type for moving TIAGo's head, provided as a typedef for convenience
typedef actionlib::SimpleActionClient<control_msgs::PointHeadAction> PointHeadClient;
typedef boost::shared_ptr<PointHeadClient> PointHeadClientPtr;
PointHeadClientPtr pointHeadClient;
ros::Time latestImageStamp;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function Definitions
void imageCallback(const sensor_msgs::ImageConstPtr& imgMsg);
void onMouse( int event, int u, int v, int, void* );
void createPointHeadClient(PointHeadClientPtr& actionClient);
#endif
tutorial_node.cpp
#include <tutorial_node/tutorial_node.h>
{actual code contents}
In my_node.h, I include tutorial_node.h, which contains some of the includes I actually need for my_node.cpp. For example, I need the pointHeadClient object defined in tutorial_node.h, as well as the actionlib/client/simple_action_client.h. Is that the proper way of including or are those spaghetti headers? If those are, what's the better way to handle this?
I suspect that's where my error is coming from so I'll save you the specifics so that I can figure the actual error out myself once this header problem is clear.
I have an array called vel declared inside global.h and defined inside global.cpp. When I try to use it inside a function, get_velocities(), of another class called Robot (inside Robot.cpp), it says:
undefined reference to `vel'
Here are the three files:
1) global.h
#ifndef GLOBAL_H_INCLUDED
#define GLOBAL_H_INCLUDED
#include <array>
using std::cout;
using std::cin;
using std::endl;
using std::array;
static constexpr const int marker_num = 10;
static constexpr const int dim = (2 * marker_num) + 3;
extern array <float, 3> vel;
#endif // GLOBAL_H_INCLUDED
2) global.cpp
#include <iostream>
#include <cstdio>
#include <cmath>
#include "global.h"
#include "WorldState.h"
#include "Robot.h"
#include "Sensor.h"
#include "Marker.h"
array <float, 3> vel = {0.0, 0.0, 0.0};
3) Robot.cpp
#include <iostream>
#include <cstdio>
#include <cmath>
#include "global.h"
#include "WorldState.h"
#include "Robot.h"
#include "Sensor.h"
#include "Marker.h"
Robot::Robot(float a, float b, float c){
//ctor
x = a;
y = b;
theta = c;
}
void Robot::get_velocities(){
v_tx = 1.0;
v_ty = 0.0;
omega_t = 0.0;
vel = {v_tx, v_ty, omega_t};
}
Edit:
I did read this question . What I realized was that the global variable requires not just a declaration but also a definition. I have provided this definition inside global.cpp. Also when I include #include "global.cpp" in Robot.cpp, it works (But this is not an acceptable practice). So, I believe this error is due to global.cpp not linking properly.
1) Isn't it a common practice to declare global variables in global.h and keep the definitions in global.cpp? How do I link them properly? I believe that one way is to create a proper make file. However, I am using codeblocks IDE. How do I do it in this IDE?
2) Is it better to eliminate global.cpp and do all definitions for global variables and functions inside the main or the file that uses them?
Declare and define the array vel within global.h. Maybe storing them within the same class would help.
My problem was that the Codeblocks IDE was not linking global.cpp. I found the answer here (first answer). I apologize if this question is a duplicate or combination of duplicates.
I'm having this issue where I cannot call the object constructor in main.cpp even after it has been included in main.h. The error message is:
C:\Users\Espresso\Projects\AZRA\Debug/../src/main.cpp:7: undefined reference to `g_editor::LevelEditor::LevelEditor()'
Where main.cpp contains
#include "main.h"
g_editor::LevelEditor g_levelEditor;
and main.h contains:
#include "g_editor/g_editor.h"
g_editor.h contains all of the header files of the objects in the library, which includes the levelEditor. g_editor.h:
#ifndef G_EDITOR_H_
#define G_EDITOR_H_
#pragma once
#include "g_editor/Objects/editor_module.h"
#include "g_editor/Objects/utility_window.h"
#include "g_editor/Objects/prompt_window.h"
#include "g_editor/LevelEditor/LevelEditor.h"
extern g_editor::LevelEditor g_levelEditor;
#endif
And finally, LevelEditor.h contains the constructor and member functions of LevelEditor:
#ifndef G_LEVEL_EDITOR_H_
#define G_LEVEL_EDITOR_H_
#pragma once
#include "../Objects/editor_module.h"
#include "Modules/collisionGrid_module.h"
#include "Modules/HUD_module.h"
#include "Modules/IO_module.h"
#include "Modules/ledge_module.h"
#include "Modules/segment_module.h"
#include "g_level/g_level.h"
using namespace g_level;
namespace g_editor
{
class LevelEditor
{
private:
std::vector<editor_module*> modules;
void loadModules();
public:
static LevelEditor& get()
{
static LevelEditor sSingleton;
return sSingleton;
}
LevelEditor();
~LevelEditor() {};
I apologize for the wall of text, I've been staring at this for a few days now and I have tried reordering the static libraries by precedence (which eliminated all issues save for this one.) Is there a design flaw in my current setup? I am using sSingletons, global externs, and static libraries.
There is no definition of LevelEditor::LevelEditor.
You are either missing a source file, or you forgot to add {}.
Edit: or, if your constructor does not do anything anyway, just remove the declaration.
Either
1) This function is missing:
LevelEditor(); // So now what does this do???? That's what is missing.
or
2) it isn't missing, but you didn't add the source module or library where this function is located to your linker settings.
#ifndef _MY_OPENCLPLATFORM_
#define _MY_OPENCLPLATFORM_
#include "OpenCL.h"
namespace my
{
class OpenCLPlatform
{
cl_platform_id mplatformID;
cl_uint mnumDevices;
std::vector<OpenCLDevice> mdevices; // OpenCLDevice was not declared in this scope
public:
OpenCLPlatform(cl_platform_id platformID);
void getDevices();
void printInfo();
cl_platform_id& getPlatformID();
};
}
#endif
#ifndef _MY_OPENCLDEVICE_
#define _MY_OPENCLDEVICE_
#include "OpenCL.h"
namespace my
{
class OpenCLDevice
{
cl_device_id mdeviceID;
public:
OpenCLDevice(cl_device_id device);
void printInfo();
void printDeviceType(cl_device_type deviceType);
};
}
#endif
#ifndef _MY_OPENCL_
#define _MY_OPENCL_
#if defined(__APPLE__) || defined(MACOSX)
#include <OpenCL/opencl.h> // This works only for XCODE compiler
#else
#include <CL/cl.h>
#endif
#include <cassert>
#include <iostream>
#include <vector>
#include "Exception.h"
#include "OpenCLDevice.h"
#include "OpenCLPlatform.h"
namespace my {
class OpenCLDevice;
class OpenCLPlatform;
class OpenCL;
class OpenCL
{
cl_uint mnumPlatforms;
std::vector<OpenCLPlatform> mplatforms;
void getPlatforms();
public:
OpenCL();
~OpenCL();
void quickSetup();
void printPlatformVersions();
};
}
#endif
Does the the ordering "class OpenCLDevice; class OpenCLPlatform; class OpenCL;" matter? Sometimes, header files depend on each other which can lead to "hard to follow" or convoluted inclusions...Do you have a "one way" technique to deal with convoluted inclusions that you use all the time?
Edit:
I changed the code to match my real problem. If you look at the code above, the compiler is saying that 'OpenCLDevice was not declared in this scope'.
Edit:
I finally got the code to work, and this is what I did:
1. add #include "OpenCLDevice.h"in OpenCLPlatform.h
2. compile
3. remove #include "OpenCLDevice.h"in OpenCLPlatform.h
4. compile
It works now!
Edit:
I cleaned the project and removed all dependencies, and I'm getting the same errors again.
Edit:
I think compiler did something to the code. It may have chose to not include libraries that aren't used in the header and source file, but are used in other headers and source codes
Since you are including classa.h and classb.h where both classes are (presumably) defined, you shouldn't even need the forward declaration.
However, if you did not include them, then no, order of the declarations wouldn't matter. As long as as a class is forward declared before it is used you should be OK.
I see two potential issues:
Your #include "OpenCL.h" may not include the file you expect (yours), but instead some system file.
Forward declarations can't be used in your case. It works only when you have pointers or references to class instances. Your vector<OpenCLPlatform> requires the class declaration (i.e. inclusion of the corresponding header).
I'm making an app with DragonFireSDK and I want to organize my multi thousand line app with .cpp and .h files
I get tons of errors when trying to do stuff though
So my app.cpp (main, required one) looks like this
Code:
#include "DragonFireSDK.h"
#include "SaveData.h"
#include "Structures.h"
#include "Definitions.h"
#include "Variables.h"
#include "SaveData.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Functions.cpp"
#include "AppMain.cpp"
#include "AppExit.cpp"
#include "OnTimer.cpp"
The #include "SaveData.h" through #include "Variables.h"
all have something like
Code:
#ifndef _HeaderName
#define _HeaderName
//STUFF HERE LIKE
#define player1 0
#define player2 1
//OR
typedef struct _number {
int view;
int number;
bool able;
int opacity;
};_number number[4];
//OR
int whoseturn;
int bet[5];
bool reachedmax[5];
int playerimg[5];
#endif
Now I may be doing something wrong already but here's some more...
My AppMain.cpp, OnTimer.cpp etc look like this
(AppMain(), etc are required functions too)
Code:
#include "DragonFireSDK.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Definitions.h"
#include "Structures.h"
#include "Variables.h"
#include "SaveData.h"
#include "Functions.cpp"
void AppMain() {
//STUFF HERE
};
Now this is where I think the problem is...
Functions.cpp
Code:
#include "DragonFireSDK.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "SaveData.h"
#include "Structures.h"
#include "Definitions.h"
#include "Variables.h"
//SOME FUNCTIONS
void SavePlayerMoney();
void SetInfo (int idnum, bool actuallyset = false);
void SwitchButton (int idnum, bool makeactive=true);
void DisableButton (int idnum);
double round (double number);
void SavePlayerMoney() {
//...
}
void SetInfo(int idnum, bool actuallyset) {
//...
}
void SwitchButton(int idnum, bool makeactive) {
//...
}
void DisableButton(int idnum){
//...
}
Now the errors I get after I thought if fixed all the stuff...
Code:
1>AppMain.obj : error LNK2005: "void __cdecl SwitchButton(int,bool)" (?SwitchButton##YAXH_N#Z) already defined in App.obj
1>AppMain.obj : error LNK2005: "double __cdecl round(double)" (?round##YANN#Z) already defined in App.obj
1>AppMain.obj : error LNK2005: "void __cdecl SetInfo(int,bool)" (?SetInfo##YAXH_N#Z) already defined in App.obj
1>AppMain.obj : error LNK2005: "int __cdecl Digits(int)" (?Digits##YAHH#Z) already defined in App.obj
Any help is very greatly appreciated!
Don't #include the .cpp files.
The C compilation model is that each function is defined precisely once, i.e. in exactly one compilation unit (i.e. one object file). You compile each source file independently into a separate object file (#include-ing header files so that the compiler knows e.g. the prototype of functions to be used). You then link these separate object files together to form the final executable.
If you #include the .cpp files, you will end up with the same function being defined in multiple compilation units (remember that #include is basically equivalent to copy-pasting the contents into the file that's doing the including). So the linker will get confused, and give you the messages that you are seeing.
UPDATE
Oh, I see the problem is that you don't have a corresponding header file for Functions.cpp. The idea is that you also write a Functions.h, along the lines of:
#ifndef FUNCTIONS_H_
#define FUNCTIONS_H_
void SavePlayerMoney();
void SetInfo(int idnum, bool actuallyset);
void SwitchButton(int idnum, bool makeactive);
void DisableButton(int idnum);
#endif
And then you #include this header file, rather than the .cpp file.
The linker complains because functions are defined more than once. A function may only be defined in one translation unit (cpp file, after compilation it becomes an obj file) - except if it is declared inline.
You're including Functions.cpp in other units, so the function definitions from Function.cpp get duplicated into those, thus causing the linker trouble.
The solution would be to declare the functions inline - or, even better, declare them in a header (i.e. Functions.h) and define them in Functions.cpp. Any users of those functions may then #include Functions.h and have access to these functions even though they don't know their implementation.
To declare a function, do: int foo();, to actually define it, do int foo() { your code goes here}.
I think everyone answered this really well so I'm just going to give you my C++ philosophy on big projects because it seems like it is information that you may find useful.
ALWAYS separate function declarations and implementation.
It will make your life considerably easier. Declare function prototypes in a .h file, then write the implementation in a .cpp file.
For example:
// mystuff.h
#ifndef MYSTUFF_H
#define MYSTUFF_H
int myFunction(int value, char letter);
#endif
And in my .cpp file:
// mystuff.cpp
#include "mystuff.h"
int myFunction(int value, char letter) {
// insert implementation here
}
Why do this? Well one great reason is that when your code doesn't work (as it ostensibly will, an inescapable reality for any programmer), you can substitute out your .cpp file with alternate implementations without modifying the structure of your code. Not only that, there are various tricks you will discover that will rely on separating declarations and implementation that will ease your life considerably. Bottom line, do it.
Attempt encapsulation wherever possible.
If you're doing a big project (and you will notice this is true for most big projects you encounter), encapsulating similar functions, variables, and the like will save you considerable time and energy. It seems like you're making a program to play a game- have you thought about encapsulating each player into a Player or Human class, with class-specific functions for each one? If you're a C++ or Java junkie like myself, you will find that an object-oriented approach is the most effective approach 99 times out of 100 (the 1% of situations is usually where you have helper functions that don't really fit in any of the objects you've defined).
Also, encapsulation enables you to take advantage of the two other fundamental principles of object-oriented design- polymorphism and inheritance. For example, you could define a Player class, then if your game involves a computer player and a human player, you could write a separate class for each of them that inherits the basic functionality of a Player but implements each function of a Player in a different way (i.e. if there is a makeMove function, you would have a different implementation for a human than a computer. Thus, inheritance greatly simplifies your job). There are obviously many qualities of OO design that are appealing, but for what I've gleaned from your code, I'd say you would benefit the most from these ones.
Obviously, this is my own philosophy and not one that I wish to forcefully impose on you. But hopefully you will take a few helpful tips out of my terse rambling to improve the way you write code and/or avoid long lists of errors. Best of luck!
Move your function declarations to header files. For example, looks like Functions.h should contain:
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
//SOME FUNCTIONS
void SavePlayerMoney();
void SetInfo (int idnum, bool actuallyset = false);
void SwitchButton (int idnum, bool makeactive=true);
void DisableButton (int idnum);
double round (double number);
#endif
Then Functions.cpp can just include Functions.h instead of those declarations. Some header files may need to include other header files to get the appropriate types.
Finally, never #include a *.cpp file.