为什么当函数参数是const引用T时,模板参数推导T'跳过数组元素的常数? [英] Why does template parameter deduction for T 'skips' the constness of array elements when function parameter is const reference to T?

查看:125
本文介绍了为什么当函数参数是const引用T时,模板参数推导T'跳过数组元素的常数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们考虑这些定义:

/*** full type information with typeid ***/
template <class> class Type{};

template <class T> std::string typeStr()
{ return typeid(Type<T>).name(); }

/*** function template for parameter deduction ***/
template <class T> void func(const T &a)
{
    std::cout << "Deduced type for T is: " << typeStr<T>() << std::endl;
    std::cout << "\targument type is: " << typeStr<decltype(a)>() << std::endl;
}



指向const的指针



如果执行以下语句:

with pointers to const

If the following statements are executed:

const int i=5, *ip=&i;
func(ip);

输出为:

Deduced type for T is: 4TypeI**PKi**E

因此, T 实际上被推断为指向常量整数的指针。参数是一个引用到const的事实不会改变推导,这是一个人所期望的,因为指针的常量是低级的。

So T is actually deduced as a pointer to a constant integer. The fact that the argument is a reference-to-const does not change the deduction, which is what one would expect because the constness of the pointer is low-level.

但是,如果执行以下语句:

Nonetheless, if following statements are executed:

const int ia[3] = {3, 2, 1};
func(ia);

输出为:

Deduced type for T is: 4TypeI**A3_i**E

因此, T 实际上是作为一个3个整数整数的数组推导出来的。参数是一个引用到const 确实改变了的推导,好像 const 正在滑入数组元素。

So T is actually deduced as an array of 3 non-const integers. The fact that the argument is a reference-to-const does change the deduction, as if the const was slipping into the array elements.

实际上,CL的版本到18是推导 T 作为3个整数的数组是我期望的标准,但是似乎从v19它收敛到GCC和Clang正在做什么(即,推导为 - 结束)。

Actually, versions of CL up to 18 were deducing T as array of 3 const integers was what I expected to be standard, but it seems that since v19 it converged to what GCC and Clang are doing (i.e., deducing as non-const).

我认为后来的行为是标准的,但是是理由吗?

Thus, I assume the later behaviour to be standard, but was is the rationale ? It could seem surprising that it does not behave like with pointers.

编辑: em> dip 注释,我将在这里报告与此行为相关的CWG问题的指针,他实际上发布为对发表评论的指针这个回答(答案实际上提出了这个新问题... C ++感觉像一个很深的隧道)

Following dip comment, I will report here pointers to CWG issues related to this behaviour, pointers he actually posted as a comment on this answer (answer that actually raised this new question... C++ feels like a deep tunnel)

  • CWG 1059
  • CWG 1610
  • CWG 112

推荐答案

使用此函数模板原型:

template <typename T> void func(const T& a);

在第一个例子中,类型扣除的工作原理如下:

In your first example, the type deduction works as:

const int* ip;

func(ip) => func<const int*>(const (const int*)& a)
                 ^^^^^^^^^^         ^^^^^^^^^^

注意:这是伪代码。整个类型是 const int * const&

Note: This is pseudocode. The full type is const int* const&.

注意 / code>保留 const int ,但 * 变为 * const

Note that the const int remains const int, but the * becomes * const.

这是因为 const int * 只是一个常规,可变,非易失性指针。它只是一个 *

This is because const int* is just a regular, mutable, non-volatile pointer. It is just a *. What it points to is irrelevant.

但在第二个例子中,您有:

But in the second example, you have:

const int ia[3];

func(ia) => func<int[3]>(const (int[3])& a)
                 ^^^^^^         ^^^^^^

注意:这是伪代码。真正的类型是 const int(& a)[3]

Note: This is pseudocode. The real type would be const int (&a)[3].

在这两种情况下,丢弃外部 const

So the type deduction is working the same in both cases, discarding the outer const.

const 数组与 const 元素的数组相同。

It so happens that a const array is the same as an array of const elements.

写类型如下:

template <typename T> func(T const & a);

int const * ip;

func(ip) => func<int const *>(int const * const & a)

int const ia [3];

func(ia) => func<int [3]>(int const (& a) [3])



第二个例子, const 似乎移动应用于数组上应用于元素。这是因为你不能真正有一个 const 数组,只有一个 const 元素的数组。

On that second example, the const appears to "move" from being applied on the array to being applied on the elements. This is because you can't really have a const array, only an array of const elements.

这篇关于为什么当函数参数是const引用T时,模板参数推导T'跳过数组元素的常数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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