与C++模板混淆

mat*_*thk 2 c++ templates programming-languages semantics

我正在查看一些c ++代码,并且在这种情况下不理解模板声明的目的:

template<> void operator>>(const ClassA& s, const ClassB d) {...}
Run Code Online (Sandbox Code Playgroud)

什么是语义template<>

Gor*_*pik 11

事实上,这是模板专业化,正如前面提到的其他人一样.必须有一些先前声明的函数模板,例如:

template<typename T, typename U>
void operator>>(const T& s, const U d) {...}
Run Code Online (Sandbox Code Playgroud)

但是,这是非常误导的.template<>完全删除它会好得多,所以operator>>只会过载.函数模板特化的问题在于它可能在存在重载函数时导致意外行为(并且operator>>具有大量重载),因为特化不会过载.这意味着编译器首先为函数选择最合适的重载,然后,如果选定的重载是函数模板,它会查找模板特化以查看是否有合适的重载.

一个经典的例子(不幸的是,我不记得我在哪里阅读它).考虑这个重载的函数模板:

template <typename T>
void Function(T param);

template <typename T>
void Function(T* param);

template <>
void Function(int* param);

main()
{
  int i = 5;
  Function(&i);
}
Run Code Online (Sandbox Code Playgroud)

正如所料,int*调用模板特化.但只需更改函数定义的顺序:

template <typename T>
void Function(T param);

template <>
void Function(int* param);

template <typename T>
void Function(T* param);

main()
{
  int i = 5;
  Function(&i);
}
Run Code Online (Sandbox Code Playgroud)

现在T*调用通用模板,因为我们专门为模板而T不是for T*,而第二个模板更适合我们的调用.如果我们重载函数而不是专门化模板,这将被避免:

void Function(int* param);
Run Code Online (Sandbox Code Playgroud)

现在声明的顺序无关紧要,我们将始终调用重载int*.

更新:现在我知道应该归功于谁.我在Herb Sutter 的一篇文章中读到了这一点.这个例子由Peter Dimov和Dave Abrahams提供.