簡體   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