2011-08-18 102 views
13

在C++ 0x(哦!读取C++ 11)中,我们有自动类型推断。让我好奇的一件事是我无法创建一个自动变量数组。例如:为什么我不能创建一个自动变量数组?

auto A[] = {1, 2, 3, 4}; // Error! 

任何想法为什么这可能被禁止?

+3

提到为什么每个人都希望滥用新的语言特性的可变参数模板黑客。 –

+3

@Martin:我绝对没有滥用像C++这样非常漂亮的语言的意图。我只是对这个决定背后的原因(技术,道德等)感到好奇。 –

+2

@Martin:在开始盲目运行之前,您必须触摸表面以了解墙壁的位置。 – Klaim

回答

10

auto推导出每个大括号包含的初始化列表为std::initializer_list<T>。 (请参见包含示例的第7.1.6.4.6节)。 不幸的是,一旦你获得了它,你就不能初始化一个阵列,或者从std::initializer_list开始std::array,但是你可以使用std::vector

#include <vector> 
#include <array> 
#include <initializer_list> 

int main() 
{ 
    auto x = {1,2,3}; 
    std::array<int, 3> foo1 = x; // won't work for whatever reason 
    std::vector<int> foo2 = x; // works as expected 
    return 0; 
} 

当然,这会破坏你想要做的全部目的。

我试着写一个叫到身边make_array工作,但必须认识到,这永远不能工作作为initializer_list的大小不是其模板参数的一部分,所以你唯一的实例为每一个T模板make_array。这很糟糕。

template<typename T> 
auto make_array(const std::initializer_list<T>& x) 
    -> std::array<T, x.size()> { } // maaah 

好吧,显然你可以去这里How do I initialize a member array with an initializer_list?

5

因为{1, 2, 3, 4}纯粹是一个句法结构 - 它不是一个表达式,也没有类型。因此,auto无法从中推断出它的类型。

+2

这样的耻辱,我知道已经能够做多年的语言 – hamstergene

+4

但'auto x = {1,2}'声明'x'为'std :: initializer_list '。所以这不完全正确。 – pmr

+1

@DeadMG:好的,那你怎么看待auto x = {1,2,3,4};?它会不会起作用? x包含什么值?如果x是1,那么编译器现在如何扣除它的类型? –

相关问题