Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template constructor defined in the same header but outside the class is unidentified

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);
          ^
like image 302
Isura Manchanayake Avatar asked Jan 31 '26 18:01

Isura Manchanayake


2 Answers

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';
}
like image 138
vlind Avatar answered Feb 02 '26 08:02

vlind


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);
like image 30
Barry Avatar answered Feb 02 '26 07:02

Barry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!