简体   繁体   English

模板化函数专精:链接器错误

[英]Templated function specialization: linker error

I am trying to specialize a function of two template arguments, when template argument types are same. 当模板参数类型相同时,我试图专门化两个模板参数的功能。 I do it the following way: 我这样做的方式如下:

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

This code compiles fine (GCC 4.8.2) but linker gives undefined refernces to all the fun calls when U and T are same type. 这段代码编译得很好(GCC 4.8.2),但是当UT是同一类型时,链接器会给所有fun调用提供未定义的引用。 Why doesn't it work? 为什么不起作用?


Linker output : 链接器输出

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

THE PROBLEM 问题

Your fun that is using std::enable_if to protect instatiation from two types that differs has a major problem; 使用std::enable_if来保护两种不同类型的instatiation的fun是一个主要问题; it cannot implicitly deduce type T . 它不能隐含地推断出类型T

This means that when you are calling fun with b1 and b2 as parameters you are instantiating template<typename U, typename T> int fun( U& u, T t ) , which hasn't got a definition.. hence the linker error. 这意味着当你用b1b2作为参数调用fun ,你实例化template<typename U, typename T> int fun( U& u, T t ) ,它没有定义..因此链接器错误。


THE SOLUTION 解决方案

There are many alternatives to the code written below, but I reckon this might clear out some confusion. 下面写的代码有很多替代方案,但我认为这可能会清除一些混乱。

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

In the above the compiler can deduce both T and U in our template, there is also no need for an explicit specialization of said template; 在上面,编译器可以在我们的模板中推导出TU ,也不需要对所述模板进行明确的专门化; we can make use of C++'s rules for overloading and have the compiler decide when int&, float is a better match than deducing U&, T . 我们可以利用C ++的重载规则,让编译器决定int&, float是否比推导U&, T更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM