[英]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 int i=5, *ip=&i;
func(ip);
輸出是:
Deduced type for T is: 4TypeI**PKi**E
因此, T
實際上被推導為指向常數整數的指針。 參數是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.