Phorce
Phorce

Reputation: 2664

Why can't you use auto as a template type argument (e.g. std::array<auto, 5>)?

Why is this not allowed, for example:

std::array<auto, 5> myArray {

};

It would make my life so much easier, as I would be allowed to store multiple data-types inside the array. I'm sure there's a logical explanation, just wondered what it was.

Upvotes: 8

Views: 2856

Answers (3)

cdmh
cdmh

Reputation: 3344

auto is used to deduce one type from an expression. Using your suggested syntax would not help because exactly one type can be stored in a container. If you need a way to store any type in the container, take a look at boost::any, so you can use

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

Upvotes: 12

AnT stands with Russia
AnT stands with Russia

Reputation: 320401

auto is not some sort of magical flexible data type that can store any type of data. auto is a mere compiler keyword that tells the compiler that it has to deduce the specific type automatically. The type is deducted at compile time, meaning that auto is implicitly replaced with a specific type. One specific type. There's no way auto would somehow help you to store different types of data in the same array.

And in order for the actual type to be deducible, the compiler must have enough information to deduce it. In your example the relationship between the auto and the data that must be used to perform deduction (the initializers in the {} list) is not known to the compiler, which is why auto does not work in this context.

For example (borrowing the example from the comments), when you write something like this

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

the entire declaration is built entirely from core language constructs. The compiler immediately knows that the values in {} are initializers for array elements, whose type is described by keyword auto. So, the meaning of auto is easy to define using the core language concepts.

But in a declaration like

std::array<auto, 5> myArray  = { 1, 2, 3, 4, 5 };

the template std::array is seen by the compiler proper as a user-defined data type. The relationship between the values in {} and template arguments is also user-defined and hidden inside the implementation of std::array. It can be arbitrarily complex. It is not even known whether such relationship exists. And this is why it generally not possible to derive the actual type of auto is such cases.

Upvotes: 9

Mike Seymour
Mike Seymour

Reputation: 254431

Why is this not allowed

To allow that, you'd need a way for a template to specify how to infer template parameters from an object's initialiser. That would be quite a large and complicated change to the language, for little benefit.

It would make my life so much easier, as I would be allowed to store multiple data-types inside the array.

No, it wouldn't. An array can only contain a single type; all this would allow you to do is deduce that type from the initialisers (if they all had the same type), which is of limited use.

In general, auto represents a static type, inferred from the type of an expression. It sounds like you want either:

  • an ordered collection of objects of different static types. This is available in the C++11 standard library as std::tuple; or
  • an array of dynamically typed objects. There is no such thing (as yet) in the language or standard library; but boost::any or boost::variant will give you such a thing.

Upvotes: 7

Related Questions