简体   繁体   English

当函数参数是const引用T时,为什么T'的模板参数推导会跳过数组元素的常量?

[英]Why does template parameter deduction for T 'skips' the constness of array elements when function parameter is const reference to 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;
}

with pointers to const 用指针指向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

So T is actually deduced as a pointer to a constant integer. 因此, T实际上被推导为指向常数整数的指针。 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. 参数是const的引用这一事实不会改变推论,这是人们所期望的,因为指针的常量是低级的。

but with array of const 但是使用const数组

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

So T is actually deduced as an array of 3 non -const integers. 因此, T实际上被推导为3个对齐整数的数组。 The fact that the argument is a reference-to-const does change the deduction, as if the const was slipping into the array elements. 参数是const的引用这一事实确实改变了推论,就好像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 (ie, deducing as non -const). 实际上,最多18个CL的版本推导T作为3个const整数的数组是我期望的标准,但似乎从v19它收敛到GCC和Clang正在做的事情(即推导为非 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. 它看起来不像指针一样令人惊讶。


Edit: 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问题,指针他居然张贴在评论这个答案 (答案,实际上提出了这个新的问题?C ++感觉就像一个深隧道)

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

Note: This is pseudocode. 注意:这是伪代码。 The full type is const int* const& . 完整类型是const int* const&

Note that the const int remains const int , but the * becomes * const . 请注意, const int仍然是const int ,但*变为* const

This is because const int* is just a regular, mutable, non-volatile pointer. 这是因为const int*只是一个常规的,可变的,非易失性的指针。 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)
                 ^^^^^^         ^^^^^^

Note: This is pseudocode. 注意:这是伪代码。 The real type would be const int (&a)[3] . 真实的类型是const int (&a)[3]

So the type deduction is working the same in both cases, discarding the outer const . 因此类型推导在两种情况下都是相同的,丢弃外部const

It so happens that a const array is the same as an array of const elements. 碰巧const数组与const元素数组相同。

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. 在第二个例子中, const似乎“移动”从应用于数组到应用于元素。 This is because you can't really have a const array, only an array of const elements. 这是因为你没有真正有一个const数组,只有数组const元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么参数推导在此模板模板参数中不起作用 - Why parameter deduction doesn't work in this template template parameter 为什么 char 数组可以是模板参数但 const char* 不能 - Why can an array of char be a template parameter but a const char* can't 为什么模板参数会丢失常量? - Why is the template parameter losing constness? const引用模板参数中的函数? - const reference to a function in a template parameter? 标准::跨度<const t>作为 function 模板中的参数</const> - std::span<const T> as parameter in function template 为什么这样调用构造函数时模板参数推导失败? - Why does template parameter deduction fail when calling the constructor like this? 无法理解C ++ 11模板函数参数推导 - Can't understand C++11 template function parameter deduction 功能模板参数推导 - Function template parameter deduction 为什么 T&amp;&amp; 参数保留参数的常量和左值/右值属性,而 T&amp; 没有 - Why does a T&& parameter preserves the constness and lvalue/rvalue property of the argument while a T& doesn't 当参数类型为C ++ 11中的常量左值引用与非常量左值引用时,函数模板类型推导的工作方式 - How function template type deduction works when parameter type is const lvalue reference vs non-const lvalue refernce in c++11
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM