模板函数的小烦恼

Small annoyance with template function

本文关键字:烦恼 函数      更新时间:2023-10-16

好的,假设我有一个这样的函数

template <typename T>
void Func(std::vector<T> x, T alpha = 1)
{
    // ... do stuff
}

,我想把它用在一个复杂的类型上,像这样

std::vector<std::complex<double>> x;
Func(x, 5.5);

然后编译器抱怨(VS2010) template parameter 'T' is ambiguous,因为它是could be 'double' or 'std::complex<double>'。明显的修复,像这样调用

Func(x, std::complex<double>(5.5));

但是,那,我不想要。为什么不能自动转换为复杂类型?

它不起作用的原因是因为第一个参数导致T被推断为std::complex<double>,而第二个参数导致它被推断为double。它在演绎论证时根本不考虑转换。显然,这使得演绎有歧义。

您可以在identity帮助器的帮助下强制第二个参数类型为不可演绎的:

template <typename T>
struct identity { typedef T type; };
template <typename T>
void Func(std::vector<T> x, typename identity<T>::type alpha = 1)
{
    // ... do stuff
}

这个怎么样?

template<typename T>
struct identity {
    typedef T type;
};
template <typename T>
void Func(std::vector<T> x, typename identity<T>::type alpha = 1)
{
    // ... do stuff
}

第二个实参将不参与模板形参的推导,将使用vector模板实参

如果需要一个默认实参的类型与包含的类型不同,只需使用两种不同的类型:

template <class T, class U>
void Func(vector<T> x, U y);

如果你不喜欢标识帮助器,只是希望它是可转换的,试试这个:

template <typename T, typename U>
void Func(const std::vector<T>& x, U alphaU = 1)
{
    const T alpha(alphaU); // Convert to T
    // ... do stuff
}

更新:

回复你的评论:我在http://liveworkspace.org上尝试了几个编译器,这个代码对我来说很好:

#include <vector>
#include <complex>
template <typename T, typename U>
void Func(const std::vector<T>& x, U alphaU)
{
   const T alpha(alphaU); // Convert to T
   (void) x;
   (void) alpha;
}
template <typename T>
void Func(const std::vector<T>& x)
{
    Func( x, 1 );
}    
int main()
{
   std::vector<std::complex<double>> v(10);
   Func( v, 5.5 );
   Func( v );
}