【问题标题】:Templated function specialization: linker error模板函数特化:链接器错误
【发布时间】:2014-05-25 19:39:27
【问题描述】:

当模板参数类型相同时,我正在尝试专门化两个模板参数的函数。我这样做的方式如下:

#include <iostream>
#include <type_traits>

using namespace std;

template<typename U, typename T>
int fun( U& u, T t );

template<>
inline
int fun( int& u, float t )
{
    cout << "int, float" << endl;
    return 0;
}

template<typename U, typename T>
inline
int fun( U& u, typename std::enable_if<std::is_same<U, T>::value ,T>::type t )
{
    cout << "U == T" << endl;
    return 0;
}

int main()
{
    int a;
    float b1, b2;

    fun(a, b1);
    fun(b1, b2);

    return 0;
}

这段代码编译得很好(GCC 4.8.2),但是当UT 是同一类型时,链接器会为所有fun 调用提供未定义的引用。为什么它不起作用?


链接器输出

g++ -std=c++11 test.cpp

/tmp/cc7HWboz.o: In function `main':
test.cpp:(.text+0x66): undefined reference to `int fun<float, float>(float&, float)'
collect2: error: ld returned 1 exit status

【问题讨论】:

  • TU 不同时是否没有链接器错误?
  • @KerrekSB 正确,具体示例见编辑后的帖子

标签: c++ templates c++11 linker specialization


【解决方案1】:

问题

您的fun 使用std::enable_if 来防止两种不同类型的实例化存在一个重大问题;它不能隐式推断类型T

这意味着当您使用b1b2 作为参数调用fun 时,您正在实例化template&lt;typename U, typename T&gt; int fun( U&amp; u, T t ),它没有定义......因此出现链接器错误。


解决方案

下面编写的代码有很多替代方案,但我认为这可能会消除一些混乱。

template<
  typename U,
  typename T,
  typename = typename std::enable_if<std::is_same<U, T>::value>::type
>
inline int fun( U& u, T t)
{
    cout << "U == T" << endl;
    return 0;
}

inline int fun( int& u, float t )
{
    cout << "int, float" << endl;
    return 0;
}

在上面编译器可以在我们的模板中推导出TU,也不需要该模板的显式特化;我们可以利用 C++ 的重载规则,让编译器决定何时int&amp;, float 比推导U&amp;, T 更好。

【讨论】:

  • 谢谢。我试过fun&lt;float, float&gt;(b1, b2),效果很好。
猜你喜欢
  • 1970-01-01
  • 2014-10-21
  • 2012-12-14
  • 2018-08-19
  • 2017-10-20
  • 2011-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多