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

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

问题描述

让我们考虑一下这些定义:

Let's consider those definitions:

/*** 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);

输出是:

The output is:

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

输出是:

The output is:

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和锵正在做的(也就是说,演绎为 -const)。

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.

编辑:以下的的评论,我会在这里报告指针到与此相关的行为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

推荐答案

使用这个函数模板的原型:

Using this function template prototype:

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)
                 ^^^^^^^^^^         ^^^^^^^^^^

注:这是伪code。完整的类型是 const int的* const的&放大器;

请注意, const int的遗体 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)
                 ^^^^^^         ^^^^^^

注:这是伪code。真正的类型将是 const int的。(安培;一)[3]

所以类型推演工作同样在这两种情况下,丢弃外侧常量

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

事实上,有一个常量数组是一样的常量元素的数组。

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

这可能有助于写类型是这样的:

It might help to write types like this:

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])

在这第二个例子中,常量似乎从阵列上被应用到的元素被应用移动。这是因为你没有真正有一个常量阵中,只有常量元素的数组。

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.

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

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