2016-04-15 83 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 - >指针的指针到整型变量