[英]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),但是当U
和T
是同一类型时,链接器会给所有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. 这意味着当你用b1
和b2
作为参数调用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; 在上面,编译器可以在我们的模板中推导出T
和U
,也不需要对所述模板进行明确的专门化; 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.