为什么链接器会在此模板中抱怨多个定义?

ove*_*der 15 c++ templates template-specialization

当包含在至少两个翻译单元(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
Run Code Online (Sandbox Code Playgroud)

但是用一个翻译单元编译和链接很好.如果我删除了专业化,它在所有情况下都能正常工作.这是链接器消息:

g++ -o test.exe Sources\test.o Sources\other_test.o
Sources\other_test.o:other_test.cpp:(.text+0x0): multiple definition of `int maximum<int>(int const&, int const&)'
Sources\test.o:test.cpp:(.text+0x14): first defined here
Run Code Online (Sandbox Code Playgroud)

模板是否允许多次实例化?如何解释此错误以及如何解决?

谢谢你的建议!

Dan*_*ani 31

这是因为完整的显式模板特化只能定义一次 - 虽然链接器允许多次定义隐式特化,但它不允许显式特化,它只是将它们视为普通函数.
要修复此错误,请将所有特化项放在源文件中,如:

// 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 ;
}
Run Code Online (Sandbox Code Playgroud)


Ayj*_*jay 13

声明函数内联

// 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 ;
}
Run Code Online (Sandbox Code Playgroud)