Originally published on Cohost.
Why doesn’t the following code run? (comments represent different files):
// foo.hpp
template <typename T>
struct Foo {
static void foo(void);
}
// foo.cpp
#include <iostream>
#include "foo.hpp"
template <>
struct Foo<int> {
static void foo() { std::cout << "foo\n"; }
}
// main.cpp
#include "foo.hpp"
int main(void) {
Foo<int>::foo();
}
Answer
From this SO post. Basically, foo.cpp
needs to be
#include <iostream>
#include "foo.hpp"
template struct Foo<int>;
void Foo<int>::foo() { std::cout << "foo\n"; }
because otherwise, member function definitions are secretly inline
, and since there is no usage site in the same compilation unit they won’t get exported as symbols. Declaring them like this lets them be non-inline, and the symbol can be used in the other compilation unit.
hell language btw.