与C ++模板混淆

时间:2011-01-17 09:05:58

标签: c++ templates programming-languages semantics

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

template<> void operator>>(const ClassA& s, const ClassB d) {...}

template<>的语义是什么?

4 个答案:

答案 0 :(得分:11)

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

template<typename T, typename U>
void operator>>(const T& s, const U d) {...}

然而,这是非常误导的。最好完全删除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);
}

正如预期的那样,调用了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);
}

现在为T*被调用,因为我们是专业模板的通用模板T,而不是T*,这第二个模板更适合于我们的电话。如果我们重载函数而不是专门化模板,则可以避免这种情况:

void Function(int* param);

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

更新:现在我知道应该归功于谁。我在Herb Sutter的article中读到了这个。这个例子是由Peter Dimov和Dave Abrahams提供的。

答案 1 :(得分:2)

template specialization :(完全或部分)解析特定类型的模板。 (您的特定示例似乎是一个完整的专业化,因为其中没有更多的模板参数未解析。如果模板有多个参数,并且您只专门设置其中一些参数,则称为部分模板专业化

这允许为给定模板提供特定于类型的优化,或者执行许多巧妙的技巧,例如检测变量的静态类型等。

答案 2 :(得分:2)

答案 3 :(得分:2)

如果要为特定模板类型提供特殊处理程序,请使用此语法。考虑:

// A normal template definition.
template <typename AType>
whoami () {   std::cout << "I am an unknown type.";  }

// Now we specialize.
template <>
whoami<int> () {   std::cout << "I am an integer!";  }

还有其他一些废话,特别是“部分专业化”,但这是template <>的基本功能。