I am having a hard time understanding why the following won't link. The error (GCC 8.3) is
ld: In function `Foo<&(void bar<double>())>::doThing()':
main.cpp: undefined reference to `void bar<double>()'
The code in question:
main.cpp:
#include "base.hpp"
// Links and runs fine if explicitly instantiated:
// Foo<bar<double>> fbd;
int main(int, char**) {
Base<int> d;
return 0;
}
base.hpp:
#pragma once
#include "foo.hpp"
#include "bar.hpp"
// Links fine if Base is not a template
template<typename T>
class Base {
public:
Base() {
Foo<bar<double>> fbd1;
Foo<bar2> fbd2;
fbd1.doThing(); // If doThing is not virtual and not called it links fine
fbd2.doThing();
}
};
foo.hpp:
#pragma once
template<void (*callMe)()>
class Foo {
public:
// If doThing is not virtual, it links fine
virtual void doThing() {
callMe();
}
};
bar.hpp:
#pragma once
#include <iostream>
// If bar is not a template, it links fine
template<typename T>
inline void bar() {
std::cout << "hello1" << std::endl;
}
inline void bar2() {
std::cout << "hello2" << std::endl;
}
I am obviously missing something, because to me it looks like the compiler should be able to see and produce the required template specializations. Any suggestions on how to fix this, and pointers on why the changes marked with comments resolve the linker problems, would be appreciated.
Update:
This seems to compile fine on clang 7.1.0.