【问题标题】:Why the linker complains about multiple definitions in this template? [duplicate]为什么链接器抱怨此模板中有多个定义? [复制]
【发布时间】:2011-12-14 13:49:29
【问题描述】:

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

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

感谢您的建议!

【问题讨论】:

  • 你可能应该从你的函数中返回一个引用。
  • 这只是跟踪我在更复杂的代码中遇到的错误的一个例子。我认为这个例子可以更清楚,没有任何参考:)

标签: c++ templates template-specialization


【解决方案1】:

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

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

【讨论】:

  • 非常感谢!刚想问你头文件怎么重写!
【解决方案2】:

内联声明函数

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

【讨论】:

  • 非常感谢!如果我们可以将您的答案与 Dani 的答案合并,我认为我们可以获得完整而准确的答案。
猜你喜欢
  • 2016-01-15
  • 1970-01-01
  • 2016-03-30
  • 2015-10-08
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多