与 C++ 混淆了模板

发布于 2024-10-12 12:15:47 字数 195 浏览 8 评论 0原文

我正在查看一些 C++ 代码,但不明白在这种情况下模板声明的目的:

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

template<> 的语义是什么?

I am looking at some c++ code and do not understand the purpose of the template declaration in this situation:

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

What is the semantic of template<>?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

ゃ懵逼小萝莉 2024-10-19 12:15:47

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

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 的文章中读到了这一点。该示例由 Peter Dimov 和 Dave Abrahams 提供。

This is, indeed, template specialization, as others before mentioned. There must be some previously declared function template, such as:

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

However, it is quite misguided. It is much better to remove the template<> altogether, so operator>> would just be overloaded. The problem with function template specialization is that it may lead to unexpected behaviour in the presence of overloaded functions (and operator>> has lots of overloads), since the specialization does not overload. This means that the compiler first selects the most appropriate overload for the function and then, if the selected overload is a function template, it looks for template specializations to see if there is an appropriate one.

A classical example (unfortunately, I don't remember where I read it). Consider this overloaded function template:

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

As expected, the template specialization for int* is called. But just change the order of the function definitions:

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

Now the general template for T* is called, since we are specializing the template for T, not for T*, and this second template is better suited for our call. This would be avoided if we overloaded the function instead of specializing the template:

void Function(int* param);

Now the order of declaration does not matter, we will always call the overload for int*.

UPDATE: Now I know who to credit. I read about this in an article by Herb Sutter. The example was provided by Peter Dimov and Dave Abrahams.

陈甜 2024-10-19 12:15:47

当您想要为特定模板类型提供特殊处理程序时,可以使用此语法。考虑一下:

// 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 <> 的基本功能。

You use this syntax when you want to provide a special handler for a particular template type. Consider:

// 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!";  }

There's some other nonsense involved, particularly "partial specialization", but that's the basic function of template <>.

羁〃客ぐ 2024-10-19 12:15:47

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

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

It is a template specialization: (fully or partially) resolving the template for a specific type. (Your particular example seems to be a full specialization, as no more template parameters are left unresolved in it. If the template has multiple parameters, and you specialize only some of them, it is called partial template specialization)

This allows one to provide type-specific optimizations for a given template, or to do many clever tricks such as detecting the static type of variables etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文