C++ Getting undefined symbol error - c++

I am trying to do an assignment and the program compiles fine on my home
PC (Netbeans) but when I try and compile on the Uni Sun box I get the following error
compile flags : g++ -lm -ansi -Wall -pedantic skyhigh.cpp -o skyhigh
Undefined first referenced
symbol in file
Flight::GetSeats() /var/tmp//cc49OAwj.o
Flight::GetCost() /var/tmp//cc49OAwj.o
Flight::GetAircraft() /var/tmp//cc49OAwj.o
ld: fatal: Symbol referencing errors. No output written to skyhigh
collect2: ld returned 1 exit status
Any help would be greatly appreciated,as I have spent hours combing the internet
for the solution
FLIGHT.H File
//
// flight.h
//
// Parent Flight class
//
#ifndef __FLIGHT_H__
#define __FLIGHT_H__
#include<iostream>
#include<string>
using namespace std;
/*TO DO REQUIRED HEADER FILES AND NAMESPACES*/
class Flight
{
protected:
string aircraft;
string category;
int seats;
double cost;
public:
virtual ~Flight(){};
// virtual void Display() =0;
void SetAircraftType(string air);
string GetAircraft();
int GetSeats();
double GetCost();
void SetSeats(int seat);
//TO DO
// Prototypes of all the Item functions
};
#endif
FLIGHT.CPP FILE
#include "flight.h"
string Flight::GetAircraft(){
return aircraft;
}
int Flight::GetSeats(){
return seats;
}
double Flight::GetCost(){
return cost;
}
void Flight::SetSeats(int seat){
seats=seat;
}
void Flight::SetAircraftType(string category){
aircraft = category;
}
MAIN FILE
// skyhigh.cpp for CPT 323 Assignment 1 SP3 2013
//
//
// CPT323 2013 assignment 1
#include "skyhigh.h"
/////////////////////////////////////////////////////
int main()
{
Flight newflight ;
cout<< "Plane Name:" <<newflight.GetAircraft()<< " Seats: "<< newflight.GetSeats()<<"Cost: "<<newflight.GetCost()<< endl;
Scenic newflight2 ;
//cout<< "Plane Name:" <<newflight2.GetAircraft()<< " Seats: "<< newflight2.GetSeats()<<"Cost: "<<newflight2.GetCost()<< endl;
//Scenic* sptr=&newflight2;
//BookingSheet booking;
//cout<< booking.GetDay()<<booking.GetTime()<<booking.GetPassengerName()<<booking.GetPaymentStatus()<<endl;
int finished = 0;
do {
/*Create array for use in menu options*/
cout << "Main Menu : " <<endl;
cout << "1) Add a flight booking "<<endl;
cout << "2) Remove a flight booking "<<endl;
cout << "3) View current booking sheet " <<endl;
cout << "0) Exit \n" <<endl;
cout<< "Please make a selection (0-3) ";
int selection;
cin>> selection;
/*Capture user selection default in switch statement validates 1-9*/
// fgets(option,sizeof(option),stdin);
//
//
switch (selection) {
case 0:
cout << "Thanks for using the SkyHigh Booking System"<<endl;
finished=1;
break;
case 1:
cout << "1) Add a flight booking "<<endl;
break;
case 2:
cout << "2) Add Customer "<<endl;
break;
case 3:
cout << "3) Display Stock " <<endl;
break;
default:
printf("Valid input is 0-3 \n");
}
}
while(!finished);
return 0;
}
MakeFile
skyhigh: skyhigh.o utility1.o flight.o scenic.o aerobatic.o
g++ skyhigh.o utility1.o flight.o scenic.o aerobatic.o -o skyhigh
skyhigh.o: skyhigh.cpp skyhigh.h flight.h aerobatic.h scenic.h
g++ -ansi -Wall -pedantic -gstabs -c skyhigh.cpp
utility1.o: utility1.cpp utility1.h
g++ -ansi -Wall -pedantic -gstabs -c utility1.cpp
flight.o: flight.cpp flight.h aerobatic.h scenic.h
g++ -ansi -Wall -pedantic -gstabs -c flight.cpp
scenic.o: scenic.cpp scenic.h
g++ -ansi -Wall -pedantic -gstabs -c scenic.cpp
aerobatic.o: aerobatic.cpp aerobatic.h
g++ -ansi -Wall -pedantic -gstabs -c aerobatic.cpp
clean:
rm -f *.o core *.report *.errs

It can't find the object file where those missing functions are defined. Make sure you are adding the generated object file for linking. Something like that (main is the exec name and main.o is the object with the main function, change them as needed):
g++ -o main main.o skyhigh.o utility1.o flight.o scenic.o aerobatic.o

Related

Unused variable warning even when explicitly using it inside IF statement

I am trying to create (using C++17) a simple debug header that only executes some lines of code if the flag LOGGER_DEBUG_MODE is enabled. This is how my header is defined (I also tried using { x; } instead of x but the warning persists):
debug.h
#ifndef _HDEBUG
#define _HDEBUG
static bool LOGGER_DEBUG_MODE = true;
#define R_DEBUG(x) if(LOGGER_DEBUG_MODE == true) x
#endif
I included debug.h and at some point of my code I call the macro function R_DEBUG to print some values:
logger_adc.cpp
double anlg_device_t::eval_formula()
{
double result = -9999;
try
{
result = parser.Eval();
}
catch (mu::Parser::exception_type &e)
{
std::cout << e.GetMsg() << std::endl;
}
R_DEBUG(std::cout << "Eval Result: " << result << std::endl);
return result;
}
I expected everything to work properly but when I run the makefile I got this warning:
inc/debug.h:5:14: warning: 'LOGGER_DEBUG_MODE' defined but not used [-Wunused-variable]
static bool LOGGER_DEBUG_MODE = true;
I thought that my definition was messed up but after checking the temporary files created by g++, it appears that the preprocessor did everything as I expected:
logger_adc.ii
double anlg_device_t::eval_formula()
{
double result = -9999;
try
{
result = parser.Eval();
}
catch (mu::Parser::exception_type &e)
{
std::cout << e.GetMsg() << std::endl;
}
if(LOGGER_DEBUG_MODE == true) std::cout << "Eval Result: " << result << std::endl;
return result;
}
Why do I get the warning message even when the variable LOGGER_DEBUG_MODE is clearly being used inside the if statement? Did I mess up something obvious that I'm not picking up? My compile flags for the object files (where the warning occurs) are g++ -Wall -Wextra -O1 -g -std=c++17 -save-temps=obj -Iinc -I/usr/local/include -c plus pkg-config --cflags --libs libmodbus
If needed, this is my main function:
main.cpp
#include "logger_adc.h"
int main()
{
anlg_device_t test (ADC_CHIP_1, 1, 18, 1, 1, true);
test.set_formula("2*x","x", test.get_voltage_ptr());
std::cout << "Test Voltage: " << test.get_voltage() << std::endl << "Test Relative: " << test.get_relative() << std::endl;
std::cout << "Test Formula (2*x): " << test.eval_formula() << std::endl;
return 0;
}
Thanks in advance!
You have a header that defines a static bool LOGGER_DEBUG_MODE =true;. If you include that header in multiple C++ files then each file will gets its own copy of that bool.
In your main.cpp you aren't using R_DEBUG so the copy of that bool (which presumably comes from including logger_adc.h ) is indeed unused in that file.
Possible solutions are:
You should make it so you only have a single copy of that bool (declare it in the header with extern and define it in a single C++ file.
Use build defines instead of runtime checks
etc

no member named 'array' in namespace 'std'

I am learning C++ right now and i get this somewhat weird error.
The Code is as follows:
#include <iostream>
#include <array>
using std::cout;
using std::endl;
using std::ostream;
using std::array;
template <typename T, size_t dim>
ostream& operator<<(ostream& os, const array<T,dim>& a) {
os << "[ ";
for (auto n : a)
os << n << " ";
os << "]";
return os;
}
int main()
{
cout << endl << "--- " << __FILE__ << " ---" << endl << endl;
array<int,3> a1 { 2,3,5 }; // (A)
array<int,0> a2 { }; // (B)
array<int,2> a3 { 1 }; // (C)
// array<int> x1 { 1, 2, 3 }; // (D)
// array<int,3> x2 { 1,2,3,4 };
array<int,3> a4 = { 1,2,3 }; // (E)
array<int,3> a5 { { 4,5,6 } }; // (F)
cout << "01| a1=" << a1 << endl;
cout << "02| a2=" << a2 << endl;
cout << "03| a3=" << a3 << endl;
cout << "04| a4=" << a4 << endl;
cout << "05| a5=" << a5 << endl;
cout << endl << "--- " << __FILE__ << " ---" << endl << endl;
return 0;
}
My IDE (Visual Studio Code) shows me the error, although the code is compiling and working.
Here is the makefile provided by our Prof.
# compiler settings
CXX = g++-7
# CXX = clang++
CXXFLAGS = -ansi -pedantic -Wall -Wextra -Wconversion -pthread -std=c++17
LDFLAGS = -lm
# collect files
CXXEXAMPLES = $(shell find . -name '*.cpp' -print -type f)
CXXTARGETS = $(foreach file, $(CXXEXAMPLES), ./out/$(file:.cpp=.out))
# build them all
all: $(CXXTARGETS)
out/%.out: %.cpp
$(CXX) $(CXXFLAGS) $< $(LDFLAGS) -o $#
clean:
rm out/*
I use Ubuntu 16.04 and thought it might be a compiler problem, so I changed "CXX" to "CXX = g++-7", because we were recommended to use g++ Version 7 but it didn't helped.
On typing "g++ -v" it shows that my gcc is version 5.5.0, but typing "apt list -installed" shows that g++-7 is installed.
I did not find any solution on the internet as most similar problems often revolved around missing includes.
VS Code also does not recognize some types of variable definitions like
"int n{1}"
It also complains about the "use of undeclared identifier" on the lines (A) to (E)
I assume the problem lies within the VS Code compiler using a different/old syntax recognition. But I don't know how to change that.

Errors when linking and compiling C++ files using TextPad/G++, possibly (probably) just syntax?

This very well could be a syntax error on my part since I am rather new with using multiple files and structs in C++ (in particular, passing structs to functions). Here are the three files:
main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include "common.h"
using namespace std;
void honorStatus(int, student studentList[]);
int main(void)
{
int header;
string filename;
ifstream inputFile;
student studentList[MAX_STUDENTS];
// Get filename from user and try to open file
cout << "Please enter a filename: ";
cin >> filename;
inputFile.open(filename.c_str());
// If file cannot be opened, output error message and close program
if (inputFile.fail())
{
cout << "Input file could not be opened. Please try again." << endl;
return 1;
}
// Get header number from file. If header is larger than max number
// of students, error is output and program is closed
inputFile >> header;
if (header > MAX_STUDENTS)
{
cout << "Number of students has exceeded maximum of " << MAX_STUDENTS
<< ". Please try again." << endl;
return 1;
}
// Read file information (student ID, hours, and GPA) into struct array
for (int i = 0; i < header; i++)
{
inputFile >> studentList[i].ID >> studentList[i].hours >> studentList[i].GPA;
}
// Close the file
inputFile.close();
// Calls function honorStatus
honorStatus(header, studentList);
return 0;
}
functs.cpp:
#include <iostream>
#include "common.h"
using namespace std;
// Function to determine classification and honors society eligibility requirements
// of each student, outputting this information and the number of students eligible
void honorStatus(int fheader, student fstudentList[])
{
int cnt = 0;
for (int i = 0; i < fheader; i++)
{
if (fstudentList[i].hours < 30)
{
cout << "Student #" << fstudentList[i].ID << " is a freshman with GPA of "
<< fstudentList[i].GPA << ". Not eligible." << endl;
}
else if (fstudentList[i].hours > 29 && fstudentList[i].hours < 60)
{
if (fstudentList[i].GPA >= 3.75)
{
cout << "Student #" << fstudentList[i].ID << " is a sophomore with GPA of "
<< fstudentList[i].GPA << ". Eligible." << endl;
cnt++;
}
else
{
cout << "Student #" << fstudentList[i].ID << " is a sophomore with GPA of "
<< fstudentList[i].GPA << ". Not Eligible." << endl;
}
}
else if (fstudentList[i].hours > 59 && fstudentList[i].hours < 90)
{
if (fstudentList[i].GPA >= 3.5)
{
cout << "Student #" << fstudentList[i].ID << " is a junior with GPA of "
<< fstudentList[i].GPA << ". Eligible." << endl;
cnt++;
}
else
{
cout << "Student #" << fstudentList[i].ID << " is a junior with GPA of "
<< fstudentList[i].GPA << ". Not eligible." << endl;
}
}
else
{
if (fstudentList[i].GPA >= 3.25)
{
cout << "Student #" << fstudentList[i].ID << " is a senior with GPA of "
<< fstudentList[i].GPA << ". Eligible." << endl;
cnt++;
}
else
{
cout << "Student #" << fstudentList[i].ID << " is a senior with GPA of "
<< fstudentList[i].GPA << ". Not eligible." << endl;
}
}
}
cout << "\nTotal number of students eligible for the Honor Society is " << cnt << "." << endl;
}
common.h:
// Maximum number of students allowed
const int MAX_STUDENTS = 10;
// Struct for student info
struct student
{
int ID;
int hours;
float GPA;
};
When using TextPad/G++, I get the following error:
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccxq9DAh.o:p7b.cpp:(.text+0x0): multiple definition of `main'
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o:p5.cpp:(.text+0x0): first defined here
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccLa96oD.o:test.cpp:(.text+0x0): multiple definition of `main'
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o:p5.cpp:(.text+0x0): first defined here
/usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../../i686-pc-cygwin/bin/ld: /cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o: bad reloc address 0x1b in section `.text$_ZNSt11char_traitsIcE7compareEPKcS2_j[__ZNSt11char_traitsIcE7compareEPKcS2_j]'
collect2: error: ld returned 1 exit status
When using an online C++ compiler (CompileOnline), I get:
/tmp/ccIMwHEt.o: In function `main':
main.cpp:(.text+0x1cf): undefined reference to `honorStatus(int, student*)'
collect2: error: ld returned 1 exit status
I wasn't able to find a guide on how to set up TextPad/G++ to compile and link multiple files, but my instructor gave a short set of instructions that I followed. Here is how it's set up:
So this could a two-parter question (how do I set up TextPad to correctly compile/link files? why is my honorStatus() function undefined in main.cpp?) or it could just be that my syntax is wrong. I'm honestly not sure. Sorry if this is a bit long; I wanted to include as much detail as possible. Any help is greatly appreciated.
The problem is that you are compiling "*.cpp" all together. Given this
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccxq9DAh.o:p7b.cpp:(.text+0x0): multiple definition of `main'
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o:p5.cpp:(.text+0x0): first defined here
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccLa96oD.o:test.cpp:(.text+0x0): multiple definition of `main'
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o:p5.cpp:(.text+0x0): first defined here
/usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../../i686-pc-cygwin/bin/ld: /cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o: bad reloc address 0x1b in section `.text$_ZNSt11char_traitsIcE7compareEPKcS2_j[__ZNSt11char_traitsIcE7compareEPKcS2_j]'
collect2: error: ld returned 1 exit status
we can see that the the compiler has been trying to combine p5.cpp, p7b.cpp and test.cpp into one executable (possibly other .cpp files too).
You need to actually tell the compiler exactly which files you want to build together to one program. E.g.
g++ main.cpp functs.cpp -o main.exe
(I would suggest also adding -Wall -Wextra -Werror to the compile line, as that allows the compiler to detect the small mistakes that aren't strictly errors, but where you probably got something wrong)
From the linker output you can see that main function is found in these files: p7b.cpp, p5.cpp and test.cpp. As there's no main.cpp file listed in the linker output, I guess that current directory is setup to be where p7b.cpp and other files are located.
Try to change Initial Folder to be where your main.cpp file is set (something like /cygdrive/c/Users/Korina/programming/). Also, remove all unrelevant files from that directory, as you're compiling all cpp files.
The error message is clear enough. Your project contains the following files
p7b.cpp, p5.cpp, test.cpp
where in each file there is defined function main. Put a place in order with your project files.
As for the error message when you use the inline compiler then it seems module functs.cpp is not included in the project. So the compiler does not see the function definition.

Linker error multiple definition of class constructor

solved
I had to delete the old object-files and rebuilt the whole project to fix the problem. Unfortunately I don't know the very reason why I got this error.
Maybe it where some wrong placed include-statements or there may have been definitions in the class declaration of accountsContainer.h which I had removed meanwhile.
I am trying to compile a little C/C++ application and am stuck with a linking problem:
the exact error is this:
make all
g++ -g -Wall -fmessage-length=0 -I "Z:/SRS/Verwaltung/EDV/Marcus EDV/Programmierung/link libraries/c++/curl-7.24.0/include/curl/" -c -o accountsContainer.o accountsContainer.cpp
g++ -o libcurl.exe signatureUpdater.o accountsContainer.o network.o registry.o emailAccount.o filesystem.o libcurl.o "Z:/SRS/Verwaltung/EDV/Marcus EDV/Programmierung/link libraries/c++/curl-7.24.0/lib/libcurl.dll"
accountsContainer.o: In function `accountsContainer':
G:\#1Arbeit\htdocs\libcurl/accountsContainer.cpp:11: multiple definition of `accountsContainer::accountsContainer()'
signatureUpdater.o:G:\#1Arbeit\htdocs\libcurl/accountsContainer.h:13: first defined here
collect2: ld returned 1 exit status
make: *** [libcurl.exe] Error 1
I don't understand where this error comes from. I already did some research on the internet for the "multiple definition of"-error.
This is what I know:
I think you can declare classes or functions several times as often as you want, but I must only be defined once.
And this is what I did:
I defined the class constructor "accountsContainer::accountsContainer(){...}" in the accountsContainer.cpp which is never included anywhere, but should only be compiled with my make-file to accountsContainer.o
accountsContainer.h contains the declaration of the class
But why does the linker complain about a definition of accountsContainer::accountsContainer(){...} in the header file?
These are my files:
"accountsContainer.h"
/*
* accountsContainer.h
*
* Created on: 16.03.2012
* Author: Admin
*/
#ifndef ACCOUNTSCONTAINER_H_
#define ACCOUNTSCONTAINER_H_
#include "emailAccount.h"
#include <string>
#include <iostream>
#include <algorithm>
class accountsContainer {
public:
const static int MAX_ACCOUNTS = 50;
private:
emailAccount srsAccounts[],emailAccounts[];
//can only be initalized in the constructor
int nAccounts;
int nSrsAccounts;
//methods
private:
void emailToLowerCase();
void findSrsAccounts();
public:
accountsContainer();
void printSrsAccounts();
emailAccount & getSrsAccount(int);
};
#endif /* ACCOUNTSCONTAINER_H_ */
"accountsContainer.cpp"
/*
* accountsContainer.cpp
*
* Created on: 16.03.2012
* Author: Admin
*/
#include "accountsContainer.h"
#include "signatureUpdater.h"
accountsContainer::accountsContainer() {
//init variables
nAccounts = 0;
nSrsAccounts = 0;
/*
* read email Accounts from registry and save them to the srsAccounts Array
*/
signatureUpdater::reg.getEmailAccounts(srsAccounts,MAX_ACCOUNTS);
//make all e-mail adresses lower case
emailToLowerCase();
findSrsAccounts();
}
void accountsContainer::printSrsAccounts(){
string locS;
for(int i=0;i < nSrsAccounts;i++){
wcout << L"Account " << i << L" : " << srsAccounts[i].displayName <<endl;
wcout << L"Name: " << srsAccounts[i].accName.c_str() << endl;
wcout << L"E-Mail:" << srsAccounts[i].email.c_str() << endl << endl;
}
}
emailAccount & accountsContainer::getSrsAccount(int i){
return srsAccounts[i];
}
void accountsContainer::emailToLowerCase(){
wstring s;
for(int i=0; i < nAccounts; i++){
s = emailAccounts[i].email;
std::transform(s.begin(), s.end(), s.begin(), std::ptr_fun<int,int>(std::tolower));
emailAccounts[i].email = s;
}
}
void accountsContainer::findSrsAccounts(){
/*
* resets Number of SRS accounts
* then iterates all e-mail accounts
* and searches for domain srsonline.de
* in lowercase!
*/
size_t found;
wstring emailAdr;
nSrsAccounts = 0;
for(int i=0;i<nAccounts;i++){
emailAdr=emailAccounts[i].email;
found = emailAdr.rfind(L"srsonline.de");
if(found != string::npos && (emailAdr.length()-found) == 12){
/*
wcout << L"für E-mail Konto: " << emailAdr << endl;
cout << "srsonline.de found at: " << found << endl;
*/
// copy SRS Accounts to srsAccounts array
srsAccounts[nSrsAccounts] = emailAccounts[i];
nSrsAccounts++;
}
}
}
and thats my makefile:
CXXFLAGS = -g -Wall -fmessage-length=0 -I "Z:/SRS/Verwaltung/EDV/Marcus EDV/Programmierung/link libraries/c++/curl-7.24.0/include/curl/" # -O2 no performance improvement because of debugging!
OBJS = signatureUpdater.o accountsContainer.o network.o registry.o emailAccount.o filesystem.o libcurl.o
LIBS = "Z:/SRS/Verwaltung/EDV/Marcus EDV/Programmierung/link libraries/c++/curl-7.24.0/lib/libcurl.dll"
TARGET = libcurl.exe
$(TARGET): $(OBJS)
$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
all: $(TARGET)
clean:
rm -f $(OBJS) $(TARGET)
I hope that the problem doesn't come from a bad programm-architectur/design
thank you for your help!
Check the include guards, maybe you use the same name in another header.

boost::python and set::erase -> weird behaviour

I'm trying to store objects in a std::set. Those objects are boost::shared_ptr<>, coming from the python environment. adding values to the set won't cause any troubles. But when I try to erase a value, even though I'm passing the very same reference, it won't work. Here is an example :
#include <set>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/python.hpp>
using namespace std;
using namespace boost;
using namespace boost::python;
struct Bar
{
Bar() {}
};
struct Foo
{
set< shared_ptr<Bar> > v_set;
shared_ptr<Bar> v_ptr;
Foo() {}
void add( shared_ptr<Bar> v_param ) {
cout << "storing " << v_param << "in v_set and v_ptr" << endl;
v_set.insert(v_param);
v_ptr = v_param;
}
void del( shared_ptr<Bar> v_param ) {
cout << "deleting " << v_param << endl;
if (v_param == v_ptr) {
cout << "v_param == v_ptr" << endl;
} else {
cout << "v_param != v_ptr" << endl;
}
cout << "erasing from v_set using v_param" << endl;
if (v_set.erase(v_param) == 0) {
cout << "didn't erase anything" << endl;
} else {
cout << "erased !" << endl;
}
cout << "erasing from v_set using v_ptr" << endl;
if (v_set.erase(v_ptr) == 0) {
cout << "didn't erase anything" << endl;
} else {
cout << "erased !" << endl;
}
}
};
BOOST_PYTHON_MODULE (test)
{
class_< Foo, shared_ptr<Foo> >("Foo")
.def("add",&Foo::add)
.def("remove",&Foo::del);
class_< Bar, shared_ptr<Bar> >("Bar");
}
compiling :
%> gcc -pthread -fno-strict-aliasing -march=i686 -mtune=generic -O2 -pipe -DNDEBUG -march=i686 -mtune=generic -O2 -pipe -fPIC -I/usr/include/python2.7 -c test.cpp -o test.o
%> g++ -pthread -shared -Wl,--hash-style=gnu -Wl,--as-needed build/temp.linux-i686-2.7/test.o -L/usr/lib -lboost_python -lpython2.7 -o test.so
and now, a small python script :
from test import *
f = Foo()
b = Bar()
f.add(b)
f.remove(b)
Here is the result :
storing 0x8c8bc58in v_set and v_ptr
deleting 0x8c8bc58
v_param == v_ptr
erasing from v_set using v_param
didn't erase anything
erasing from v_set using v_ptr
erased !
I store 0x8e89c58 inside the set and outside, just in case
I'm passing the same reference to both calls (0x8e89c58)
just to make sure i check if v == val
I try to erase by using v -- it doesn't work
I try to erase by using val -- it works !
I'm completely lost there - can't see what is causing this. Any input ?
I ran your example then added some assertions that I thought should hold in del():
assert(!(v_param < v_ptr));
assert(!(v_ptr < v_param));
One of them failed!
I dug into the implementation of operator< for boost::shared_ptr and found something strange: it compares the reference counts rather than the internal pointers! A little digging found a mailing list post about this issue with some helpful links to two C++ documents: N1590 which explains why people thought this was a good idea, and N2637 which explains why it wasn't.
It seems that the Boost people have not (yet?) adopted the N2637 recommendation, but C++11 has. So I built your test again using C++11 (g++ -std=c++0x), having removed using namespace boost; so as to use std::shared_ptr. This resulted in a horrible template-ridden error message which was solved by adding this at the top (easily derived from boost/smart_ptr/shared_ptr.hpp):
template<class T> inline T * get_pointer(std::shared_ptr<T> const & p)
{
return p.get();
}
And it works!
If you can't use C++11, just implement your own custom comparator for your set which compares the pointers sanely:
template <typename T>
struct SmartComparator
{
bool operator()(shared_ptr<T> const& lhs, shared_ptr<T> const& rhs) {
return lhs.get() < rhs.get();
}
};
Then this will work:
set< shared_ptr<Bar>, SmartComparator<Bar> > v_set;