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

发布于 2024-12-11 20:26:58 字数 753 浏览 0 评论 0原文

当包含在至少两个翻译单元(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 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

模板不允许多次实例化吗?如何解释这个错误以及如何修复它?

感谢您的任何建议!

This little piece of code triggers the linker's anger when included on at least two translation units (cpp files) :

# 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

But compiles and links fine with one translation unit. If I remove the specialization, it works fine in all situations. Here is the linker message :

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

Aren't templates allowed to be instantiated multiple times ? How to explain this error and how to fix it ?

Thanks for any advice !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

明月夜 2024-12-18 20:26:58

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

// 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 ;
}

Its because complete explicit template specializations must be defined only once - While the linker allows implicit specializations to be defined more than once, it will not allow explicit specializations, it just treats them as a normal function.
To fix this error, put all specializations in source file like:

// 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 ;
}
棒棒糖 2024-12-18 20:26:58

内联声明函数

// 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 ;
}

Declare the functions inline

// 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 ;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文