本文介绍了为什么按照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):

转换后的函数模板的函数类型为: 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.

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

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 ++模板不比接受指针的模板更专业?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 10:00