Tyson Hilmer
Tyson Hilmer

Reputation: 771

Template class with bool conversion operator and template specific instantiation does not link

I prefer to separate template declarations and definitions in headers and compilation units, and use template specific instantiation. But in this example, I cannot get the bool conversion operator definition to work in the compilation unit (foo.cpp).

foo.hpp:

// foo.hpp
#include <limits> // quiet_nan
#include <cmath>

template<class T>
struct Foo {

// Defined in .cpp does not link; undefined reference
operator bool() const;

// Defined in foo.hpp works
//explicit operator bool() const { return !std::isnan(radian); }

private:
  T radian = std::numeric_limits<T>::quiet_NaN();
};

foo.cpp:

#include "foo.hpp"
#include <cmath>

template <class T>
Foo<T>::operator bool() const { return !std::isnan(radian);}

// Template specific instantiation
template Foo<double>::operator bool() const;
template Foo<float>::operator bool() const;

main.cpp:

#include "foo.hpp"

int main(int argc, char* argv[]) {

Foo<double> wd;
Foo<float> wf;

bool bd = bool(wd);
bool bf = bool(wf);
}

Linking errors with unresolved external symbol for the bool conversion operator:

Error LNK2001   unresolved external symbol "public: __cdecl Foo<double>::operator bool(void)const "
Error LNK2001   unresolved external symbol "public: __cdecl Foo<float>::operator bool(void)const "

My question is why does definition in the .cpp compilation unit not work?

Update: Compilation with gcc works. Compilation with VS 2022 v143 does not work.

Upvotes: 1

Views: 42

Answers (0)

Related Questions