为什么链接器抱怨这个模板中有多个定义

Why the linker complains about multiple definitions in this template?

本文关键字:定义 为什么 链接      更新时间:2023-10-16

当这一小段代码包含在至少两个翻译单元(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 ;
}
相关文章: