2016-04-15 87 views
2

什麼是auto*的類型扣除規則?自動*的類型扣除規則是什麼?

考慮以下幾點:

int x = 64; 
int* px = &x; 

auto* v1 = &x; // auto => ??? ok v1 is int* ... 
auto* v2 = px; // auto => ??? is v2 int* ? 
auto* v3 = &px; // auto => ??? is v3 int** ? 

只是爲了澄清我的問題,如果我們拆分類型推演分爲兩個步驟:

  1. 推導的 「auto」 本身的類型不(*)..然後
  2. 推導出對象的類型(v1v2v3),然後將(*

所以我的兩個問題是:

  1. 會有什麼auto無(*來推斷)?
  2. v2指針指向intint*)和v3指針指針(int**)?

回答

1

如果你知道模板類型推導你幾乎可以知道全部有auto類型扣除。因爲自動類型扣除像模板類型扣除那樣工作。

當一個變量使用auto聲明,那麼auto充當T在模板,和類型說明符充當參數類型

const auto i = 20; 

將轉化爲:

template<typename T> 
void func(const T param) { ... } 
//  ^^^^^^^ 

並供參考:

const auto& j = i; 

翻譯爲:

template<typename T> 
void func(const T& param) 
//  ^^^^^^^^ 

的指針,這是相同的:

auto* v1 = &x; 

變爲

template<typename T> 
void func(T* param) 

由於xint,然後auto* == int*
auto* v2 = px;int*

現在,您有第三個:

auto* v3 = &px; 

變爲int**因爲你以指針的地址。

template<typename T> 
void func(T** param) 
//  ^^^ 

一種方便的方法,看汽車的類型是使用已經提到別人時,typeid()功能。
但我喜歡用<boost/type_index.hpp>正確顯示類型:

#include <iostream> 
#include <boost/type_index.hpp> 
using namespace std; 
using namespace boost::typeindex; 

int main() 
{ 
    int x = 64; 
    int* px = &x; 

    auto* v1 = &x; 
    auto* v2 = px; 
    auto* v3 = &px; 
    cout << type_id_with_cvr<decltype(v1)>().pretty_name() << '\n'; 
    cout << type_id_with_cvr<decltype(v2)>().pretty_name() << '\n'; 
    cout << type_id_with_cvr<decltype(v3)>().pretty_name() << '\n'; 
} 

,輸出:

int* 
int* 
int** 

有汽車類型推演和模板類型推演之間的一個重要差異,即std::initializer_list<>

考慮這些例子大小寫:

auto i = 1; // int 
auto j(1); // int 
auto k = { 1 }// std::initializer_list<int> ! 
auto l { 1 } // std::initializer_list<int> ! 

正如你所看到的,使用帶有auto的括號初始值設定可能會有問題。
但是,您可以手動編寫類型之前的牙套,以確保該類型是正確的,但我沒有看到的一點:

auto i = int{ 1 }; // type is int 

new auto rules已在Clang的3.8,使已實施它有可能使用直接列表初始化與自動(即將推出的標準)

+0

據我所知,汽車的作品完全一樣的模板...我其實瞭解大多數類型的自動和模板扣除,但混淆我的位是(自動*),如果我會擴大我的問題,我會問(T *)從模板太:)不幸的是我沒有提升庫:(但+1 ...臨屋區你好 – Laith

3

auto將推導出給定的表達式的cv-qualified類型。 auto*將推導出cv-qualified類型的表達式指向 - 如果表達式是指針 - 否則將無法編譯。

對於給定的例子中,實際v類型將是pointer to int,用相同v2,以及用於v3這將是pointer to pointer to int

如果您的第一個示例將被編寫爲auto v1 = &px,則v1的類型將保持不變。

0

扣除過程與模板參數相同。如果我做的:

int a = 0; 
auto* b = &a; 

類型的bint*。並寫入:

auto b = &a; 

將導致相同的類型,int*。 在你的例子中,編譯器會添加缺少的星。但最簡單的形式是寫auto

3

您可以使用typeid回答你的問題。

#include <iostream> 
#include <typeinfo> 
using namespace std; 

int main() { 
    // your code goes here 
    int x = 64; 
    int* px = &x; 

    auto* v1 = &x; 
    auto* v2 = px;  
    auto* v3 = &px; 
    cout<<typeid(v1).name()<<endl; 
    cout<<typeid(v2).name()<<endl; 
    cout<<typeid(v3).name()<<endl; 
    return 0; 
} 

輸出:

Pi 
Pi 
PPi 

丕 - >指向整數變量

的PPi - >指針的指針到整型變量