I have stripped everything out of a project I was working on to try and figure out what is causing a linker error. I am trying to write a wrapper function around std::getline
to customize its behaviour.
The following compiles, but fails with this linker error:
.../bin/ld: CMakeFiles/a.out.dir/main.cpp.o: in function `main':
main.cpp:(.text+0x8b): undefined reference to `std::basic_istream<char, std::char_traits<char> >& myfunctions::GetLine<char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)'
collect2: error: ld returned 1 exit status
make[2]: *** [a.out] Error 1
make[1]: *** [CMakeFiles/a.out.dir/all] Error 2
make: *** [all] Error 2
Here's the MWE code:
// main.cpp
#include "mygetline.h"
#include <iostream>
#include <fstream>
int main(int argc, char* argv[])
{
const std::string filename("trialbalance.csv");
std::string line;
std::ifstream ifs(filename);
myfunctions::EraseCRLF(line); // seems to be fine
myfunctions::GetLine(ifs, line); // definitely not fine
return 0;
}
// mygetline.h
#ifndef MYGETLINE_H
#define MYGETLINE_H
#include <iostream>
#include <string>
namespace myfunctions
{
void EraseCRLF(std::string &s);
template<class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>& GetLine(
std::basic_istream<CharT,Traits>& input,
std::basic_string<CharT,Traits,Allocator>& str);
}
#endif // MYGETLINE_H
// mygetline.cpp
#include "mygetline.h"
#include <iostream>
#include <string>
#include <algorithm>
namespace myfunctions
{
void EraseCRLF(std::string &s)
{
s.erase(std::remove(s.begin(), s.end(), '\r' ), s.end());
s.erase(std::remove(s.begin(), s.end(), '\n' ), s.end());
}
template<class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>& GetLine(
std::basic_istream<CharT,Traits>& input,
std::basic_string<CharT,Traits,Allocator>& str)
{
auto& ret = std::getline(input, str);
myfunctions::EraseCRLF(str);
return ret;
}
}
This one has me completely baffled because the EraseCRLF
function compiles and links ok. This suggests to me the problem is associated with the templates which are being used rather than the namespace the function is in.