为什么按照GCC 5.3和Clang 4.0,接受数组的C ++模板不比接受指针的模板更专业? [英] Why is a C++ template accepting an array not more specialized than one accepting a pointer according to GCC 5.3 and Clang 4.0?

查看:81
本文介绍了为什么按照GCC 5.3和Clang 4.0,接受数组的C ++模板不比接受指针的模板更专业?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么接下来的两个模板声明不明确(所以没有一个比另一个更专业)?我知道在Stack Overflow上已经多次提出这个问题,但通常人们会回答如何解决歧义,而不是为什么会发生歧义。

Why are the next two template declarations ambiguous (so neither is more specialized than the other)? I know this question has been raised many times on Stack Overflow, but usually, people answer how to resolve ambiguity, not why it's happened.

I。
模板< class T> void func(char * buf,T size){}

II。
模板< std :: size_t N> void func(char(& buf)[N],std :: size_t大小){}

试图通过C的步骤++ 14解决部分功能模板排序的标准(14.5.6.2):

Trying to pass steps of the C++14 standard to resolve partial function template ordering (14.5.6.2):


为每种类型生成转换后的模板,类型或模板模板参数(包括
个模板参数包(14.5.3))分别合成一个唯一的类型,值或类模板
并将其替换为函数类型中该参数的每次出现

To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs (14.5.3) thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template.

转换后的函数模板的函数类型为: void func(char *,U1),其中 U1 是某些唯一的合成类型。

Transformed function I template's function type is: void func(char*, U1), where U1 is some unique synthetic type.

转换后的函数II模板的函数类型为: void func(char(& buf)[N1],std :: size_t),其中 N1 是唯一的综合值。

Transformed function II template's function type is: void func(char (&buf)[N1], std::size_t), where N1 is some unique synthetic value.


使用转换后的函数模板的函数类型,执行typ按照14.8.2.4中所述对另一个模板
进行推导。

Using the transformed function template’s function type, perform type deduction against the other template as described in 14.8.2.4.

所以让我们尝试在一侧执行类型推导(将第一个模板用作参数,将第二个模板用作参数模板),并放在另一侧。

So let's try to perform type deduction on one side (using the first template as an argument and the second one as a parameter template) and on the opposite side.

参数模板: template< std :: size_t N> void func(char(& buf)[N],std :: size_t大小)
转换后的参数模板: void func(char *,U1)

试图推导模板参数。无法从 char * 类型推导出 char(& buf)[N] 。 U1也不匹配 std :: size_t 类型。

Trying to deduce template parameters. "char (&buf)[N]" can't be deduced from "char*" type. U1 doesn't match std::size_t type either. Failed.

参数模板: template< class T> void func(char * buf,T size)
转换后的参数模板: void func(char(& buf)[N1],std :: size_t)

试图推断模板参数。参数模板的第一个参数完全没有类型,并且与 char [] 兼容。 T 应该推导为 std :: size_t

Trying to deduce template parameters. The first argument of parameter template is not type at all and it's compatible with a char[]. T should be deduced to std::size_t.

因此,模板II应该更加专业,并应在以下代码中进行选择:

So template II should be more specialized and should be selected in the following code:

char buf[16];
func(buf, static_cast<std::size_t>(16));

为什么对于GCC 5.3和Clang 4.0并非如此?

Why is this not true for GCC 5.3 and for Clang 4.0?

推荐答案

模板声明不是模棱两可;以下代码将编译并运行正常:

The template declarations are not ambiguous; the following code compiles and runs OK:

#include <iostream>
#include <string>

using namespace std;

template<class T>
void func(char* buf, T size) {cout<<"void func(char*,T)\n";}
template<size_t N>
void func(char (&buf)[N], std::size_t size) {
  cout<<"void func(char (&)[],size_t)\n";}

int main() {
  char buf[3];
  func(buf, 2);
  func<3>(buf, 2);
  func(reinterpret_cast<char (&)[3]>(buf), 2);
  //next is ambiguous
  //func(reinterpret_cast<char (&)[3]>(buf), size_t(2));
  func<3>(reinterpret_cast<char (&)[3]>(buf), size_t(2));
  return 0;
}

但是,被注释掉的调用是模棱两可的。要消除歧义,请使用:

However, the commented-out call is ambiguous. To disambiguate it use:

func<3>(reinterpret_cast<char (&)[3]>(buf), size_t(2));

此方法正常,并调用正确的函数。

This works OK and calls the correct function.

这篇关于为什么按照GCC 5.3和Clang 4.0,接受数组的C ++模板不比接受指针的模板更专业?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆