I know template class definitions should be defined in the header file. However, the constructor defined in the header but outside the class seems to be unnoticed by the compiler while the constructor defined inside the class works just fine. Am I missing something completely obvious?
This works
#include <type_traits>
#include <iostream>
struct A {
template<typename T,
typename = typename std::enable_if<std::is_integral<T>::value>::type>
A(T t) {
this->t = static_cast<double>(t);
}
double t;
};
int main() {
A a(3);
std::cout << a.t << '\n';
}
This does not
#include <type_traits>
#include <iostream>
struct B {
template<typename T, typename> B(T t);
double t;
};
template<typename T,
typename = typename std::enable_if<std::is_integral<T>::value>::type>
B::B(T t) {
this->t = static_cast<double>(t);
}
int main() {
B b(3);
std::cout << b.t << '\n';
}
saying
error: no matching function for call to 'B::B(int)'
B b(3);
^
You forgot a few things. The defaulted template argument should be in the class declaration. And you'll need a typename added to that.
#include <type_traits>
#include <iostream>
struct B {
template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type> B(T t);
double t;
};
template<typename T,
typename>
B::B(T t) {
this->t = static_cast<double>(t);
}
int main() {
B b(3);
std::cout << b.t << '\n';
}
Yeah I think this is just a gcc bug. Filed 88864.
This is a shorter reproduction that should compile but doesn't (clang accepts):
struct B {
template<typename T, typename U> B(T t);
};
template <typename T, typename U = int>
B::B(T t) { }
B b(3);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With