samedi 4 avril 2015

g++ undefined reference to class member, although its defined [duplicate]


This question already has an answer here:




I try to compile my C++ sources with g++ with the following command:



g++ test.cpp csv_parser.cpp csv_creator.cpp
but it returns:
/tmp/ccT3y5oG.o: In function `main':
test.cpp:(.text+0xdc): Undefined reference to `csv::csv_parser<int>::set_line(std::string)'
test.cpp:(.text+0x104): Undefined reference to `csv::csv_parser<int>::get_line() const'
test.cpp:(.text+0x145): Undefined reference to `csv::csv_creator<int>::set_line(std::deque<int, std::allocator<int> >&)'
test.cpp:(.text+0x15e): Undefined reference to `csv::csv_creator<int>::get_line() const'
collect2: error: ld returned 1 exit status


I found many other entrys about that problem, but the solution was either that not all source files were given in the compiler command, or there were typing mistakes in the code, but I couldn' find one of these problems in my case, thats why I have to open a new thread. I use a template class and I have the suspicion, that the compiler doesn't know, that I need the int version of my class and so doesnt compile one, and the linker then has no int version for linking, but I'm not sure about this idea at all!


Please help me with this problem! I attach all the files.


Thank you :) DevWurm





test.cpp




#include "csv.h"
#include <fstream>
#include <deque>
#include <iostream>

using csv::csv_parser;
using csv::csv_creator;
using std::ofstream;
using std::ifstream;
using std::deque;
using std::cout;
using std::endl;
using std::getline;

int main() {
ifstream input("test.csv");
ofstream output("test2.csv");
csv_parser<int> parser;
csv_creator<int> creator;
deque<int> data;
string buffer;

getline(input, buffer);
parser.set_line(buffer);
data = parser.get_line();

creator.set_line(data);
cout<<creator.get_line();

return 0;
}



csv.h




#ifndef CSV_H_
#define CSV_H_

#include <deque>
#include <iostream>
#include <string>

using std::deque;
using std::ifstream;
using std::ofstream;
using std::string;

namespace csv {

template<typename T>
class csv_parser {
private:
deque<T> line;
public:
template<typename S>
friend csv_parser<S>& operator>> (ifstream& input, csv_parser<S>& parser); //file input stream operator
csv_parser<T>& operator>> (deque<T>target); //data output operator
deque<T> get_line() const; //get parsed line
void set_line(string input); //set line and parse
};

template<typename T>
class csv_creator {
private:
string line;
public:
template<typename S>
friend ofstream& operator<< (ofstream& output, csv_creator<S>& creator); //file output stream operator
csv_creator<T>& operator<<(deque<T>& input); //data input operator
string get_line() const; //set data and create csv
void set_line(deque<T>& input); //get created csv
};

}

#endif /* CSV_H_ */



csv_parser.cpp




#include <deque>
#include <fstream>
#include <sstream>
#include <string>
#include <algorithm>
#include "csv.h"

using std::deque;
using std::ifstream;
using std::stringstream;
using std::string;
using std::getline;
using std::copy;

namespace csv {

template<typename T>
csv_parser<T>& operator>> (ifstream& input, csv_parser<T>& parser) {
parser.line.clear();
T buffer;
string line;
stringstream converter;

getline(input, line);

while (line.size() > 0) {
if (line.find_first_of(",") != -1) {
converter << line.substr(0, line.find_first_of(","));
converter >> buffer;
parser.line.push_back(buffer);
line.erase(0, line.find_first_of(",")+1);
}
else {
converter << line.substr(0, line.length());
converter >> buffer;
parser.line.push_back(buffer);
line.erase(0, line.length());
}
}
return parser;
}

template<typename T>
void csv_parser<T>::set_line(string input) {
line.clear();
T buffer;
stringstream converter;

while (input.size() > 0) {
if (input.find_first_of(",") != -1) {
converter << input.substr(0, input.find_first_of(","));
converter >> buffer;
line.push_back(buffer);
input.erase(0, input.find_first_of(",")+1);
}
else {
converter << input.substr(0, input.length());
converter >> buffer;
line.push_back(buffer);
input.erase(0, input.length());
}
}
}

template<typename T>
csv_parser<T>& csv_parser<T>::operator>>(deque<T> target) {
target.clear();
copy(line.begin(), line.end(), target.begin());
line.clear();
return *this;
}

template<typename T>
deque<T> csv_parser<T>::get_line() const{
deque<T> buffer = line;
line.clear();
return buffer;
}

}



csv_creator.cpp




#include <deque>
#include <fstream>
#include <sstream>
#include <string>
#include "csv.h"

using std::deque;
using std::ifstream;
using std::stringstream;
using std::string;

namespace csv {

template<typename T>
ofstream& operator<< (ofstream& output, csv_creator<T>& creator) {
output << creator.line;
return output;
}

template<typename T>
csv_creator<T>& csv_creator<T>::operator<< (deque<T>& input) {
stringstream converter;
for (int i = 0; i <= input.size()-1; i++) {
if (i != input.size()-1) {
converter << input.at(i) << ',';
}
else {
converter << input.at(i);
}
}
line = converter.str();
return *this;
}

template<typename T>
string csv_creator<T>::get_line() const {
return line;
}

template<typename T>
void csv_creator<T>::set_line (deque<T>& input) {
stringstream converter;
for (int i = 0; i <= input.size()-1; i++) {
if (i != input.size()-1) {
converter << input.at(i) << ',';
}
else {
converter << input.at(i);
}
}
line = converter.str();
}

}

Aucun commentaire:

Enregistrer un commentaire