Pass reference of a smart ptr to a constructor - c++

i use qcc (qnx 660) compiler (gcc 4.7.3).
I wanted to use a reference to an object in another object.
For this I wanted to pass this in a constructor call and copy/assign it to a member instance.
As I got undefined reference errors again and again I got annoyed and converted the whole thing in a simpler way and changed a refrenz to an int variable, see example.
I came across this question, and wanted to solve it in the answer as given by #sellibitze.
Here is my code example:
foo.hpp:
#include <memory>
#include <utility>
class foo { public:
explicit foo(std::shared_ptr<int> stuff);
private:
std::shared_ptr<int> mstuff;
};
foo.cpp:
#include "foo.hpp"
explicit foo::foo(std::shared_ptr<int> stuff)
:mstuff(std::move(stuff))
{
std::cout << "done" << std::endl;
}
main.cpp:
#include <cstdlib>
#include <iostream>
#include "foo.hpp"
int main(int argc, char *argv[])
{
foo my_foo(std::make_shared<int>(10));
}
error message of compiler:
main.cpp:11: undefined reference to `foo::foo(std::shared_ptr)'
As this didn't work either, I got suspicious and recreated the example in the online compiler, https://godbolt.org/z/83hTMq1ef.
With the gcc 4.7.3 various messages come.
With a gcc >9 you only get this message :
:17:1: error: 'explicit' outside class declaration 17 |
explicit foo::foo(std::shared_ptr cnt)
| ^~~~~~~~ Compiler returned: 1
What is the smartest way to pass a shared_ptr with gcc version 4.7.3?

Related

What does this line of code mean in c++?

I cant understand this line of code from source code at github :
using NodePtr = std::shared_ptr<Node>;
I read the cppreference page here, but it didn't have any information regarding similar syntax. As much as I can guess, it is somewhat like #define in that when I use NodePtr from now on, it will replace it internally with std::shared_ptr<Node>. With that, I tried to test code but it didn't work.
Code :
test.h:
#ifndef TEST_H_
#define TEST_H_
#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
#include <utility>
#include <typeinfo>
#include <limits>
#include <functional>
namespace nnvm {
class Node;
using NodePtr = std::shared_ptr<Node>;
class Node {
public:
~Node();
inline bool is_variable() const;
inline int num_outputs() const;
inline int num_inputs() const;
};
}
#endif // TEST_H_
test.cpp:
#include "test.h"
#include <iostream>
static graphy::NodePtr Create();
int main(int argc, char const *argv[])
{
/* code */
graphy::Node *node = new graphy::Node();
std::cout << "Hello Graphy!!" << std::endl;
return 0;
}
Here is the error I get :
In file included from /usr/include/c++/5/unordered_map:35:0,
from test.h:7,
from test.cpp:1:
/usr/include/c++/5/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support \
^
In file included from test.cpp:1:0:
test.h:18:7: error: expected nested-name-specifier before ‘NodePtr’
using NodePtr = std::shared_ptr<Node>;
^
test.cpp:5:14: error: ‘NodePtr’ in namespace ‘graphy’ does not name a type
static graphy::NodePtr Create();
^
At first glance your error is due to namespaces. The using statement is in namespace nnvm and not Graphy.
'using' is similar to 'typedef'. It's an alias allowing 'nnvm::NodePtr' to represent a 'std::shared_ptr'.
update
As #UnholySheep points out, you will also need to add a compiler setting to enable c++11 support as the compiler error states.
The error messages you're seeing suggest that you're trying to compile C++11 code with an old compiler that defaults to C++98 mode. You probably need a command line switch, something like -std=c++11 (or something similar, depending on exactly which compiler you're using). Or get a new compiler.

Why does my c++ code keep returning 'undefined reference to' one of my constructors when I try to compile?

I have been trying to get my code to compile for a while. Kept looking online for a solution to my problem but I didn't find one. Some help would be appreciated.
Here are some of the files that I have:
gate.h
#ifndef GATE_H
#define GATE_H
#include <vector>
class Gate {
private:
std::vector<int> inWires, outWires;
char function;
public:
Gate (char function, const std::vector<int>& inputWires, const std::vector<int>& outputWires);
};
#endif
gate.cpp
#include "gate.h"
Gate::Gate (char functionality, const std::vector<int>& inputWires, const std::vector<int>& outputWires) {
function = functionality;
inWires = inputWires;
outWires = outputWires;
}
circuit_file_reader.h
#ifndef CIRCUIT_FILE_READER_H
#define CIRCUIT_FILE_READER_H
#include <string>
#include <iostream>
#include <vector>
#include "circuit.h"
#include "gate.h"
Circuit readCircuit(std::string filename);
#endif
circuit_file_reader.cpp
#include "circuit_file_reader.h"
Circuit readCircuit (std::string filename) {
std::vector<int> iw (1, 7);
std::vector<int> ow (1, 8);
Gate g0 ('a', iw, ow); // This is the problem
std::vector<Gate> gates;
// gates.push_back (g0);
return Circuit (gates, 0);
}
test_circuit_file_reader.cpp
#include <iostream>
#include <string>
#include "circuit_file_reader.h"
int main(int argc, char** argv) {
readCircuit("");
std::cout << "Test Worked!" << std::endl;
return 0;
}
Whenever I try to compile this code my compiler returns
circuit_file_reader.cpp:(.text+0xa5): undefined reference to `Gate::Gate(char, std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> > const&)' collect2: error: ld returned 1 exit status
Which is strange because the Gate constructor has been defined so why can't it see it?
You declared the header in the header file, but its definition lies in the source (.cpp) file. You aren't specifying this to the compiler. You didn't specify what you're using to compile but if you compile all source files properly then it should work. Here is the example using g++.
You didn't provide the required circuit.h file to compile the program, so I made a dummy one just so it could compile.
Edit: I was asked to remove the picture so here is the g++ command in text.
g++ circuit_filer_reader.cpp gate.cpp main.cpp -o test
./test
Test Worked!
If for whatever reason anyone wants to compile it here is the dummy circuit.h file.
#include "gate.h"
struct Circuit
{
Circuit(std::vector<Gate> gates, int test)
{
return;
}
};
You didn't provide your compiler command, but I guess you didn't link gate.o while trying to generate the final binary.

Passing 0 to the shared pointer with deleter as the first argument

I'm readin Scott Meyrse C++ and now I'm at the section about deigning interfaces. The following code is supposed to be invalid:
std::tr1::shared_ptr<Investment> // attempt to create a null
pInv(0, getRidOfInvestment); // shared_ptr with a custom deleter;
// this won’t compile
He gave the following explanation:
The tr1::shared_ptr constructor insists on its first parameter being a
pointer, and 0 isn’t a pointer, it’s an int. Yes, it’s convertible to
a pointer, but that’s not good enough in this case; tr1::shared_ptr
insists on an actual pointer.
I tried similar example myself http://coliru.stacked-crooked.com/a/4199bdf68a1d6e19
#include <iostream>
#include <memory>
struct B{
explicit B(void *){ }
};
void del(int*){ }
int main()
{
B b(0);
std::shared_ptr<int*> ptr(0, del);
}
and it compiles and runs fine even in spite of passing 0 as the first argument.
What did he mean actually? Isn't that relevant already?
One is from #include <tr1/memory>; the other is from #include <memory>. There is a difference:
http://coliru.stacked-crooked.com/a/f76ea0ef17227d9d
#include <iostream>
#include <tr1/memory>
#include <memory>
struct B{
explicit B(void *){ }
};
void del(int*){ }
int main()
{
B b(0);
std::tr1::shared_ptr<int*> ptr(0, del);
std::shared_ptr<int*> ptr2(0, del);
}
It gives the error for the tr1 version but not the current standard version.

multithreading - Asynchronous threads in class

I've got a class Foo, which have a main function and execute function. I want to start an unknown number of threads with the execute function, but when I try to compile the code I always get error C2064: term does not evaluate to a function taking 1 arguments.
foo.h
#ifndef BOT_H
#define BOT_H
#pragma once
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <string>
class foo
{
public:
foo(char *_server, char *_port);
~foo(void);
private:
char *server;
char *port;
void execute(char *cmd);
void main();
};
#endif
foo.c
#include <thread>
#include "bot.h"
#include "definitions.h"
using namespace std;
foo::foo(char *_server, char *_port){
...
}
bot::~bot(void) {
...
}
void bot::execute(char *command){
...
}
void bot::main(){
thread(&bot::execute, (char*)commanda.c_str()).detach();
}
How should I create threads from class member functions?
Thanks for any answer
You need a bot object to call the member function on:
thread(&bot::execute, this, (char*)commanda.c_str())
^^^^
although you really should either change the function to take either std::string or const char*. You have a minefield of undefined behaviour here, if either the function tries to modify the string, or commanda is destroyed while the thread is still using it.
A lambda may be more readable; and would also fix the lifetime fiasco by capturing a copy of the string:
thread([=]{execute((char*)commanda.c_str();})

C++ - Build Order and Dependency Problem

I seem to be misunderstanding something related to build order dependencies in C++. So I have this code, which defines a class that I use as a functionoid (object whose purpose is to substitute for passing a function pointer):
#include "Imports.h"
class X: public Y
{
public:
X (T* t) { this->t= t; }
virtual ~X(){}
virtual void draw()
{
if (t->booleanReturningFunction())
{
t->someField.draw();
}
}
T* t;
};
I'm getting a compiler error that complains about the "use of undefined type T" at the line numbers where I'm using T. However, Imports.h looks like:
//The goal of this file is to have all the typcally needed imports in one place.
#if !defined(IMPORTS_H)
#define IMPORTS_H
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <iostream>
#include <assert.h>
#include <cmath>
#include <fstream>
class T;
class X;
class Y;
#include "Y.h"
#include "X.h"
#include "T.h"
#endif // if !defined(IMPORTS_H)
With each ".h" file containing a definition of that class. Now T actually does have an X object in it (not a pointer, but an X object). But, as far as I can tell, there's no circular dependency in the build order because X only has a pointer to T, right? Is there anything I'm missing that you can see just from this code? Help is much appreciated!
Edit: I solved my problem. The issue was that I was doing the above code inside a header file. The compiler understandably couldn't compile t->booleanReturningFunction() based on a forward reference (it needed to see the class declaration to know what address to bind the function call to).
Now T actually does have an X object in it (not a pointer, but an X object).
Given this order -
class T;
class X;
class Y;
#include "Y.h"
#include "T.h" // 1
#include "X.h"
T.h has a X object as you mentioned. Until this point (1) compiler doesn't know the definition of class X. For the object to instantiate compiler should see the full class definition just not the forward declaration of X. But it seems strange that the compiler is complaining about undefined type T.
I solved my problem. The issue was that I was doing the above code inside a header file. The compiler understandably couldn't compile t->booleanReturningFunction() based on a forward reference (it needed to see the class declaration to know what address to bind the function call to).