q0987
q0987

Reputation: 35992

How type is deduced from `auto` variable

Based on my understanding, the type of a variable declared with auto is deduced from its initializer.

int main()
{
  unordered_map<string, int> dict;
  dict.insert({"a", 10});
  cout << dict["a"] << endl;

  auto iter = dict.find("a");
  if (iter != dict.end())
    iter->second = 30;

  cout << dict["a"] << endl;

  unordered_map<string, int>::iterator iterModify = dict.find("a");
  iterModify->second = 300;

  unordered_map<string, int>::const_iterator iterNonModify = dict.find("a");
  iterNonModify->second = 400; //  error: read-only variable is not assignable
}

In above example, as you can see, it seems that the type of auto is further constrained based on the usage of the defined variable iter and it's type is unordered_map<string, int>::iterator. However, without the following lines, how the compiler deduces the type of the auto correctly?

Question> Is it true that the "the type of a variable declared with auto is deduced from its initializer only"? If that is the case, why the deduced type of iter is of unordered_map<string, int>::iterator?

Upvotes: 3

Views: 310

Answers (2)

OmnipotentEntity
OmnipotentEntity

Reputation: 17131

auto is different from const. You can define:

const auto i = 5;
auto j = 5;
i = 6; //error const violation
j = 6; //OK

Similarly, you can define auto&, const auto&, auto&&, volatile auto, etc.

Because find has two function prototypes, it chooses which one based on the constness of the variable, which you have defined at mutable, so it chooses the mutable version.

In C++ standard language, there is a difference in the cv-qualifier (const, volatile) and the type-specifier (auto, auto&, auto&&), see section 7.1.6 for more details. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

Upvotes: 3

i Code 4 Food
i Code 4 Food

Reputation: 2154

Question> Is it true that the "the type of a variable declared with auto is deduced from its initializer only"?

Yes. The compiler does not take in consideration what you'll do next with that variable.

Thus, if you try to write a code like this:

auto x;
x = 5;

It won't compile, because x has no initializer when you declare it.

Stroustrup himself describes this feature as "auto -- deduction of a type from an initializer"

Edit:

If that is the case, why the deduced type of iter is of unordered_map::iterator?

Because that is the return type of unordered_map.find() as in auto iter = dict.find("a");

Upvotes: 3

Related Questions