关于'自动'演绎类型的困惑

时间:2017-08-04 08:47:54

标签: c++ c++11 types auto

import React, { Component } from 'react';
import { View, StyleSheet,Modal,ActivityIndicator,Button } from 'react-native';
import { Constants } from 'expo';

export default class App extends Component {
  state = {
    isShowModal: false,
  }
  render() {
    return (
      <View style={styles.container}>
        <Button title='show modal' onPress={() => this.setState({isShowModal: true})} />
        {this.state.isShowModal && this.showModal()}
      </View>
    );
  }

  showModal() {
    setTimeout(() => this.setState({isShowModal: false}), 5000); // just to mimic loading
    return(
      <Modal
        animationType='fade'
        transparent={true}
        visible={true}>

        <View style={{flex:1,backgroundColor:'rgba(0,0,0,.2)'}}>
          <ActivityIndicator size='large' color='red' style={{flex:1}} />
        </View>
      </Modal>
    )
  }
}



const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
  },
});

相当于

int i = 0;

然后,

int i;
i = 0;

没关系,工作正常。但是,

auto i = 0;

编译器出错。

那么,为什么编译器会出错?

10 个答案:

答案 0 :(得分:7)

它不等同,因为auto不是类型。在这两个示例中,i类型为intauto表示变量类型由它初始化的表达式类型决定(在这种情况下,它是int,因为它是文字0的类型。也就是说,

auto i = 0;

相当于:

int i = 0;

摘录

auto i;
i = 0;

没有意义,因为没有表达式,编译器可以从中推断出类型。

有人可能会争辩说编译器可能会进一步推断类型,但这对于价值不大会有额外的努力,所以它不太可能让位于未来的C ++标准中。以下示例将推断出哪种类型:

auto i;
if (...)
    i = 0;
else
    i = "WAT?";

BTW,int i = 0;相当于int i; i = 0,但不一样。首先是初始化,第二个是默认初始化,然后是赋值。对于int以外的类型,即具有非平凡构造函数和/或赋值运算符的类,这两个片段可能不等效。

答案 1 :(得分:4)

7.1.6.4自动说明符部分中的draft有此条目

  

auto和decltype(auto)类型说明符用于指定a   占位符类型,稍后将通过从中扣除来替换   初始化程序。

因此,autodecltype(auto)需要初始值设定项

auto i = 0; // ok, i is of type "int" deduced from 0's type

相当于

int i = 0;

但是

auto i; // error: no initializer, compiler fails to deduce type
i = 0;  // error: consequent error, i not declared/defined
如果没有初始化程序,编译器无法推断i的类型,

将无法编译 此外,

int i = 0; // initialized i as 0

不同
int i; // default initialized
i = 0; // invokes copy assignment

答案 2 :(得分:3)

auto i并不意味着“i可以保留任何内容,因此不要担心它是什么类型”。 C ++要求在创建对象时必须知道任何对象的类型。当您编写auto i = something;时,编译器会查看something的类型,以确定i的类型。如果没有something,则没有任何内容告诉编译器i的类型应该是什么,并且您收到错误。

答案 3 :(得分:2)

代码

auto i;
i = 0;

甚至不应该编译,因为在编译时无法确定i的类型,因为在前面的示例中没有直接赋值,因此编译器不会知道替换auto的内容i。在第一个示例中,您有auto i = 0;,直接赋值告诉编译器i应该是integer类型。

文档

答案 4 :(得分:2)

auto i;
i = 0;

由于auto从其初始值设定项中推断出i的类型,因此无法正常工作,在这种情况下,没有初始化程序

另一方面,这有效:

auto i = 0;

因为现在你有一个初始化程序 - 0 - 并且由于文字0的类型是int,所以auto i 1}}推导出{{1}}的类型。

答案 5 :(得分:1)

自动类型需要由编译器来删除,一旦类型设置就无法更改。它是一个编译时操作。因此需要初始化。这实际上是它的一点,通过将所有内容移动到=

的右侧来确保变量初始化

答案 6 :(得分:1)

auto只是意味着编译器会推断出类型。您没有提供任何信息,直到该行,它可以用来决定所需的类型和大小。

答案 7 :(得分:1)

如果使用auto定义变量,必须为其分配初始值。否则无法确定其类型,因为编译器确定的变量auto的类型是静态

C ++ 11标准:

  

7.1.6.4自动说明符

     

...

     

3否则,变量的类型是从其初始化程序推导出来的。   声明的变量的名称不应出现在   初始化表达式。

答案 8 :(得分:0)

是的,由于使用的具体类型,以下两个在允许的情况下是等效的 第二个is forbidden in constexpr-functions thoughThanks @ T.C.):

int i = 0;

int i;
i = 0;

虽然他们使用不同的方式到达那里(copy-initializationdefault-initialization退化为无初始化并与赋值相结合),as-if-rule表示它们是等效的。如果我们谈到不同的非平凡类型,情况可能会有所不同。

现在,如果我们将auto替换为int,事情会变得更复杂:
我们不再将变量的具体类型命名为we let the compiler deduce it

标准规定它只会从初始化程序中推导出来,初始化程序必须是声明的一部分 它可以轻松地看起来更远,可能至少the way return-type-deduction适用于lambdas和C ++ 14函数,这意味着第一个任务。
或者甚至可以尝试从其使用的所有地方合成兼容类型,就像其他语言一样,但这会使规则复杂化很多。

无论如何,标准不允许这样做,并且它对C ++的内容有最后的说法,所以除非有人向委员会提出令人信服的案例,否则我们会在下一个版本中对其进行更改语言。

答案 9 :(得分:0)

int i;
i = 0;

int i=0;

给出相同的可观察结果,但它们等效。前者首先声明一个变量,然后为它分配一个值,后者声明一个变量并且初始化它。所以它实际上等同于int i(0);

如果您使用更复杂的类而不是普通整数,则前一代码将调用operator =,而后者将调用复制(或移动)构造函数。

这就是auto i=0;有意义的原因:它定义了与其初始化程序相同类型的变量i(此处为普通int)。但auto i;引发了编译错误,因为在编译器处理声明时,它不知道该类型应该是什么。