Implicit class instantiations translation units: multiple definition when linking

Viewed 41

I have two static libraries linked in a resulting executable. Both of them identically define the class template fmt::formatter<shatred_ptr<T>,char> template for formatting shared_ptr<T> (for logging purposes). The definitions are identical in each library and look like this:

#include<fmt/ostream.h>
template <typename T> struct fmt::formatter<std::shared_ptr<T>,char>: ostream_formatter {};

The template is implicitly instantiated for many different Ts.

When the executable is being linked, I get complains about multiple definition of the

error: redefinition of ‘struct fmt::v9::formatter<std::shared_ptr<_Tp>, char>’

Is there a way to tell the compiler to merge the definitions, which are token-to-token identical? I tried various things like putting inline, extern, __attribute__((visibility,"hidden")) to various places; using "object" library (as CMake calls it — I assume it meas just object archive) instead of static and others.

I will appreciate an explanation of this (yet another) c++ corner; and a minimally-invasive solution.

1 Answers

Crediting @DavisHerring for noticing that the error was compile-time, not link-time (there were some semi-related linking errors before and I did not check this case again carefully). Thus I could guard the two identical definitions via a macro, as e.g. here, which fixed the case where headers from both libs were included from the main program.

#include<fmt/ostream.h>
#ifndef FMT_EIGEN_SHARED_PTR_FORMATTER
    #define FMT_EIGEN_SHARED_PTR_FORMATTER
    template <typename T> struct fmt::formatter<std::shared_ptr<T>,char>: ostream_formatter {};
#endif
Related