Good afternoon,
I am working with Boost Graph Library these days and there is a point in an example program that I cannot grasp. It has nothing to do with Boost itself, but with C++ and (basic) template handling.
If I declare the following in an ".h" file it compiles and links without problems.
Code:
template <class Name, class LocMap>
class city_writer {
public:
[...]
template <class Vertex>
void operator()(ostream& out, const Vertex& v) const {
[...]
}
};
But if I separate the implementation to a ".cpp" file as one would usually do
the following code compiles but fails to link:
Code:
template <class Name, class LocMap>
class city_writer {
public:
[...]
template <class Vertex>
void operator()(ostream& out, const Vertex& v) const;
};
And the implementation,
Code:
template<class Name, class LocMap>
template<class Vertex>
void city_writer<Name, LocMap>::operator()(ostream& out, const Vertex& v) const{
[...]
}
The linker outputs:
Code:
>> Invoking: GCC C++ Linker
>> g++ -o"BGLAstar" ./src/CSysLog.o ./src/ErrorRecord.o ./src/bglastar.o ./src/main.
>> undefined reference to `void city_writer<char const**, location*>::operator()<unsigned
>> int>(std::basic_ostream<char, std::char_traits<char> >&, unsigned int const&) const'
So I understand that maybe the correct form is
Code:
template<class Name, class LocMap>
template<class Vertex>
void city_writer<Name, LocMap>::operator()<Vertex>(ostream& out, const Vertex& v) const{
[...]
}
but this generates
Code:
>> g++ -O2 -Wno-deprecated -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/bglastar.d" -MT"src/bglastar.d" >> -o"src/bglastar.o" "../src/bglastar.cpp"
>> ../src/bglastar.cpp:26: error: non-template 'operator()' used as template
>> ../src/bglastar.cpp:26: note: use 'city_writer<Name, LocMap>::template operator()' to indicate that it is a
>> template
>> ../src/bglastar.cpp:26: error: expected initializer at end of input
>> make: *** [src/bglastar.o] Error 1
This suggests the following,
Code:
template<class Name, class LocMap>
template<class Vertex>
void city_writer<Name, LocMap>::template operator()(ostream& out, const Vertex& v) const{
[...]
}
but the compiler cannot match it with its use,
Code:
>> /usr/include/boost/graph/graphviz.hpp:256: undefined reference to `void city_writer<char const**,
>> location*>::operator()<unsigned int>(std::basic_ostream<char, std::char_traits<char> >&, unsigned int const&)
>> const'
>> collect2: ld returned 1 exit status
I looked for some theory on how to use templates in my C++ book (Herbert Schmidt) but to no success; this seems to be a problem well ahead of the level of this book.
Any concrete idea? Any suggestion about where can I find a more advanced book on these C++ topics?
Many thanks in advance.