繁体   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?

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

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

如果执行以下语句:

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

输出是:

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

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

但是使用const数组

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

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

输出是:

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

因此, T实际上被推导为3个对齐整数的数组。 参数是const的引用这一事实确实改变了推论,就好像const正在滑入数组元素一样。

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

因此,我认为后来的行为是标准的,但是理由是什么? 它看起来不像指针一样令人惊讶。


编辑:评论,我会在这里的指针报告与此相关的行为CWG问题,指针他居然张贴在评论这个答案 (答案,实际上提出了这个新的问题?C ++感觉就像一个深隧道)

使用此函数模板原型:

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

在第一个示例中,类型推导的工作原理如下:

const int* ip;

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

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

请注意, const int仍然是const int ,但*变为* const

这是因为const int*只是一个常规的,可变的,非易失性的指针。 这只是一个* 它所指的是无关紧要的。

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

const int ia[3];

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

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

因此类型推导在两种情况下都是相同的,丢弃外部const

碰巧const数组与const元素数组相同。

写这样的类型可能会有所帮助:

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元素。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM