在同一标头中定义但在类外部的模板构造函数未识别

时间:2019-01-15 15:58:49

标签: c++ templates c++17

我知道模板类定义应该在头文件中定义。但是,在标头中但在类外部定义的构造函数似乎未被编译器注意到,而在类内部定义的构造函数运行良好。我错过了完全显而易见的东西吗?

这有效

#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';
}

这不是

#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';
}

error: no matching function for call to 'B::B(int)'
     B b(3);
          ^

2 个答案:

答案 0 :(得分:2)

您忘记了几件事。 默认的模板参数应在类声明中。 并且您需要在其中添加一个类型名称。

#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';
}

答案 1 :(得分:1)

是的,我认为这只是gcc错误。提起88864

这是一个较短的复制品,应该可以编译但不能(c接受):

struct B {
    template<typename T, typename U> B(T t);
};

template <typename T, typename U = int>
B::B(T t) { }

B b(3);