The following code generates a linker error:
#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <iterator>
#include <algorithm>
#include <string>
class Writer
{
public:
Writer& operator << (const char* s)
{
for (const char* ch = s; *ch != 0; ++ch)
{
printf("%c",*ch);
}
return *this;
}
Writer& operator << (const int& i)
{
printf("%d",i);
return *this;
}
};
const char endl = '\n';
class File_Writer : public Writer
{
private:
FILE* f;
public:
File_Writer(FILE* f)
{
this->f = f;
}
};
File_Writer cout(stdout);
template<typename K>
Writer& operator << (Writer& w, const std::set<K>& set)
{
typename std::set<K>::const_iterator it = set.begin();
while (it != set.end())
{
w << *it << "\n";
it++;
}
return w;
}
Writer& operator << (Writer& w, const std::string& str)
{
w << str.c_str();
return w;
}
Writer& operator << (Writer& w, const std::set<std::string>& set);
int main()
{
std::set<std::string> myset;
myset.insert("eggplant");
myset.insert("xylophone");
myset.insert("apple");
myset.insert("carrot");
myset.insert("banana");
{
std::set<std::string>::iterator it = myset.find("banana");
if (it == myset.end())
{
cout << "Banana not found" << endl;
//std::cout << endl << *it; // SEGV:
//*it = "Fourth"; // NOT ALLOWED
}
else
{
cout << "Banana found\n";
cout << "it=" << *it << endl;
}
}
{
std::set<std::string>::iterator it = myset.find("xbanana");
if (it == myset.end())
{
cout << "xbanana not found" << endl;
//std::cout << endl << *it; // SEGV:
//*it = "Fourth"; // NOT ALLOWED
}
else
{
cout << "xbanana found\n";
cout << "it=" << *it << endl;
}
}
cout << "myset=" << myset << "\n"; // buggy line of code
return 0;
}
Here is the output from invoking G++ on the above code:
-*- mode: compilation; default-directory: "~/lisp++-projects/" -*-
Compilation started at Tue Jan 30 04:05:24
cd ~/lisp++-projects && make 2018/map/set2.run
* Compiling 2018/map/set2.cc DEBUG
g++ -g -O0 -std=c++11 -W -Wall -Wpointer-arith -Wformat -ffast-math -fno-permissive -Wno-format-contains-nul -c 2018/map/set2.cc -o 2018/map/set2.o
** Linking 2018/map/set2.exe DEBUG
g++ -lgcc -lstdc++ 2018/map/set2.o 2006/libd/libd.o -o 2018/map/set2.exe
2018/map/set2.o: In function `main':
/home/www/lisp++-projects/2018/map/set2.cc:100: undefined reference to `operator<<(Writer&, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)'
collect2: error: ld returned 1 exit status
Makefile.mk:86: recipe for target '2018/map/set2.exe' failed
make: *** [2018/map/set2.exe] Error 1
Compilation exited abnormally with code 2 at Tue Jan 30 04:05:27
Compilation started at: 20180130-040524
compilation-start-time=(23151 14388 436671 507000)
compilation-stop-time=(23151 14391 819805 265000)
Compilation took 3 seconds