可以链接器区分模板和非模板函数
Can linker differentiate between template and non-template functions?
我遇到了需要这样声明的模板朋友函数的规则:
template<typename T>
class Rational;
template<typename T>
const Rational<T> operator* (const Rational<T>& lhs, const Rational<T>& rhs);
template<typename T>
class Rational {
public:
friend
const Rational operator *<> (const Rational& lhs, const Rational& rhs);
};
template<typename T>
const Rational<T> operator* (const Rational<T>& lhs, const Rational<T>& rhs)
{
return Rational<T>();
}
int main(void)
{
Rational<int> r;
r = r * r;
return 0;
}
而不仅仅是写
template<typename T>
class Rational {
public:
friend
const Rational operator * (const Rational& lhs, const Rational& rhs);
};
template<typename T>
const Rational<T> operator* (const Rational<T>& lhs, const Rational<T>& rhs)
{
return Rational<T>();
}
并阅读了它的解释,说明:
当编译器看到合适的类定义中的朋友上线时,就会发生障碍。那一刻,它尚不知道朋友的功能本身就是模板。它假设它们是非修辞...
...此假设导致编译器生成对非模板函数的调用,但是链接器将为您提供"未定义的外部"。错误,因为您从未真正定义那些非模板函数。
,但在我的理解中,r * r
应该实例化
const Rational<int> operator* (const Rational<int>& lhs, const Rational<int>& rhs);
与Rational<int>
的朋友有何不同?
编译器/链接器可以区分模板和非网板函数吗?
根据语言的规则([temp.fct]/2(:
非模板函数与函数模板无关(即,它从未被认为是专业化(,即使它具有相同的名称和类型与潜在生成的函数模板专业化。
使用第二个片段,当Rational<int>
实例化时,朋友在其体内声明会引入 non-template的声明函数:
const Rational<int> operator*(const Rational<int>&, const Rational<int>&);
程序中不存在此函数的定义,事实上,operator*
模板甚至没有实例化,因为它将过载分辨率丢失到非模板operator*
。因此,从链接器的角度来看,根本没有operator*
。
,即使operator*
模板已实例化,也导致编译器发出
const Rational<int> operator*<int>(const Rational<int>&, const Rational<int>&);
这是与非模板operator*
的独特函数,其定义实际上是r * r
所要求的。如果链接器允许r * r
调用模板专业化,则该链接将导致r * r
调用与标准说应该调用的功能不同的函数。(但是,从技术上讲,链接器没有义务发出错误消息,因为这是"无诊断必需"错误。(
这就是为什么要事先声明operator*
模板并确保朋友声明是指该模板(或其专业化(的原因。
相关文章:
- 内联函数中具有内部链接的全局变量
- 使用C链接在函数内部创建C++模板
- 返回一个带有 std::move 的对象并链接函数
- 无法使函数公开。获取:"LNK2005"错误。如何调试链接器错误
- 链接器错误:无法解析构造函数
- 使用自定义工具集获取动态退出析构函数链接错误 - eh 矢量析构函数
- C++复制构造函数链接堆栈
- C 将外部函数链接为成员函数
- 将静态类与友元函数链接时出现奇怪错误
- 关于C++中构造函数链接的一些问题
- 构造函数/析构函数链接错误
- 查找导致库函数链接的函数
- C++虚拟覆盖函数链接器错误
- 将错误与定义的析构函数链接
- 模板函数链接器错误LNK2019
- 使用模板的构造函数链接器错误
- Qt移动构造函数链接错误
- 内联函数链接错误C++
- c++ OpenGL——gluBuild2DMipmaps函数链接错误
- 静态空函数链接错误