先解释一下我遇到的问题,通过以下代码简化说明,IDE环境是vs2022,c++20:
template <typename T>
class C{
public:
T a;
T b;
T c;
public:
C();
C(a);
C(a,b);
c(a,b,c);
};
这里给出了一个简单的模板类C,给出了四个构造函数,在外部写下了函数实现。,但是在实际使用的时候出现了一个很诡异的问题。
T t//这里指类型T的变量,并不是实际声明
C(t);//可以正常构造C
C(t,t);//不可以正常运行,红色下划线报参数类型不匹配错误
C(t,t,t);//不可以正常运行,红色下划线报参数类型不匹配错误
但是在模板类的函数声明和实现上在静态分析过程中并没有任何提示或错误警告出现,反复对照了参数表也没有问题。几经折腾之后,查找到问题如下:
template <typename T>
class C{
public:
T a;
T b;
T c;
public:
C();
C(a);
C(a,b);
c(a,b,c);
};
template <typename T>
C<T>::C(a){...}
template <typename T>
C<T>::C(a){...}//问题在这里
template <typename T>
C<T>::C(a,b){...}
template <typename T>
C<T>::C(a,b,c){...}
在实现第一个有参构造为C(a)时,无意中把代码多复制了一份,但是编译器并没有给出任何的重定义报错,而是直接屏蔽了后面其他函数,导致了在使用第二三种有参构造时找不到参数列表的问题。目前暂不清楚非模板函数以及非成员函数在哪些情况下也不会报重定义错误,欢迎大家的讨论补充。