为什么链接器抱怨这个模板中有多个定义
Why the linker complains about multiple definitions in this template?
当这一小段代码包含在至少两个翻译单元(cpp文件)中时,会触发链接器的愤怒:
# ifndef MAXIMUM_HPP
# define MAXIMUM_HPP
template<typename T>
T maximum(const T & a, const T & b)
{
return a > b ? a : b ;
}
/* dumb specialization */
template<>
int maximum(const int & a, const int & b)
{
return a > b ? a : b ;
}
# endif // MAXIMUM_HPP
但是用一个翻译单元编译和链接很好。如果我删除专门化,它在所有情况下都能正常工作。下面是链接器消息:
g++ -o test.exe Sourcestest.o Sourcesother_test.o
Sourcesother_test.o:other_test.cpp:(.text+0x0): multiple definition of `int maximum<int>(int const&, int const&)'
Sourcestest.o:test.cpp:(.text+0x14): first defined here
模板不允许被实例化多次吗?如何解释这个错误以及如何修复它?
谢谢你的建议
这是因为完整的显式模板特化必须只定义一次-虽然链接器允许隐式特化定义多次,但它不允许显式特化,它只是将它们视为普通函数。
要修复此错误,请将所有专门化放入源文件中,如:
// header
// must be in header file because the compiler needs to specialize it in
// different translation units
template<typename T>
T maximum(const T & a, const T & b)
{
return a > b ? a : b ;
}
// must be in header file to make sure the compiler doesn't make an implicit
// specialization
template<> int maximum(const int & a, const int & b);
// source
// must be in source file so the linker won't see it twice
template<>
int maximum(const int & a, const int & b)
{
return a > b ? a : b ;
}
声明内联函数
// must be in header file because the compiler needs to specialize it in
// different translation units
template<typename T>
inline T maximum(const T & a, const T & b)
{
return a > b ? a : b ;
}
/* dumb specialization */
template<>
inline int maximum(const int & a, const int & b)
{
return a > b ? a : b ;
}
相关文章:
- 为什么在定义函数之前先声明它
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 如果我重新定义 sqrt 函数,为什么使用 std::sqrt 失败?
- 为什么我不能在主函数之外定义一个类的对象(它继承了另一个类)?
- 为什么用户定义的函数不按照给定的顺序对相同长度的元素进行排序?
- 为什么我会收到警告,指出函数已使用但未定义,以及已定义但未使用?
- 模板推导:为什么函数指针模板定义在常量和/或引用时不匹配?
- 为什么转换函数声明不需要至少一个定义类型说明符
- 为什么不同类型层次结构的指针之间的dynamic_cast定义得很好?
- 为什么"weak.lock()"返回"nullptr" "auto weak=std::make_shared<int>(42);"的定义?
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 为什么从 char 转换为 std::byte 可能是未定义的行为?
- 为什么我会收到链接器错误:未定义对 ..?
- 为什么要将函数声明和定义放在单独的文件中
- 为什么 setjmp/longjmp 的这种用法是未定义的行为?
- 为什么我在 Windows API 中得到对 TextOut() 函数的未定义引用?
- 为什么累积C++定义了两个模板
- 多重定义 - 为什么我不能在标题中定义它们
- c++位域结构体大小定义(为什么它被包装得更大?)