为什么不能使用auto作为模板类型参数(例如std :: array <auto,5 =“”>)?</auto,>

时间:2013-09-09 15:03:07

标签: c++ c++11 stl

为什么不允许这样做,例如:

std::array<auto, 5> myArray {

};

这将使我的生活变得如此简单,因为我可以在数组中存储多个数据类型。我确信这是一个合乎逻辑的解释,只是想知道它是什么。

3 个答案:

答案 0 :(得分:10)

auto用于从表达式中推断出一个类型。使用建议的语法无济于事,因为只有一种类型可以存储在容器中。如果您需要一种在容器中存储任何类型的方法,请查看boost::any,以便您可以使用

std::array<boost::any, 5> myArray;

答案 1 :(得分:9)

auto不是某种可以存储任何类型数据的神奇灵活数据类型。 auto仅仅是编译器关键字,它告诉编译器必须自动推导出特定类型。该类型在编译时被扣除,这意味着auto被隐式替换为特定类型。 一个特定类型。 auto无法以某种方式帮助您在同一个数组中存储不同类型的数据。

为了使实际类型可以推断,编译器必须有足够的信息来推导它。在您的示例中,编译器不知道auto与必须用于执行推导的数据({}列表中的初始值设定项)之间的关系,这就是auto所做的事情。在这种情况下不起作用。

例如(借用评论中的例子),当你写这样的东西时

auto a[] = { 1, 2, 3, 4, 5 };

整个声明完全由核心语言结构构建。编译器立即知道{}中的值是数组元素的初始值,其类型由关键字auto描述。因此,使用核心语言概念很容易定义auto的含义。

但是在像

这样的宣言中
std::array<auto, 5> myArray  = { 1, 2, 3, 4, 5 };

模板std::array被编译器视为用户定义的数据类型。 {}和模板参数中的值之间的关系也是用户定义的,并隐藏在std::array的实现中。它可以是任意复杂的。甚至不知道这种关系是否存在。这就是为什么通常不可能导出auto的实际类型就是这种情况。

答案 2 :(得分:7)

  

为什么不允许这样做

为了实现这一点,您需要一种模板方法来指定如何从对象的初始化器推断模板参数。对于语言而言,这将是一个非常大而复杂的变化,几乎没有什么好处。

  

这将使我的生活变得如此简单,因为我可以在数组中存储多个数据类型。

不,它不会。一个数组只能包含一个类型;所有这些允许你做的是从初始化者推断出这种类型(如果它们都具有相同的类型),这是有限的用途。

通常,auto表示静态类型,从表达式的类型推断出来。这听起来像是你想要的:

  • 不同静态类型的对象的有序集合。这在C ++ 11标准库中以std::tuple的形式提供;或
  • 动态类型对象的数组。语言或标准库中没有这样的东西(至今);但是boost::anyboost::variant会给你这样的东西。