What are auto * type inference rules?

What are the rules for type inference for auto* ?

Consider the following:

 int x = 64; int* px = &x; auto* v1 = &x; // auto => ??? ok v1 is int* ... auto* v2 = px; // auto => ??? is v2 int* ? auto* v3 = &px; // auto => ??? is v3 int** ? 

Just to clarify my question, whether we split the type inference into two steps:

  • Print type " auto " without ( * ) ... then
  • Highlight object type ( v1 , v2 and v3 ) after adding ( * )

So my two questions:

  • What will auto be output without ( * )?
  • Will v2 pointer to int ( int* ) and v3 pointer to a pointer ( int** )?
+2
source share
4 answers

If you know that you will choose a template type, you will know almost everything you need for auto type output. Because automatic type inference works like template type inference.

When a variable is declared using auto , then auto acts like T in the template, and the type specifier acts like the type of the parameter:

 const auto i = 20; 

Translate to:

 template<typename T> void func(const T param) { ... } // ^^^^^^^ 

And with a link:

 const auto& j = i; 

Translated to:

 template<typename T> void func(const T& param) // ^^^^^^^^ 

With pointers, it's the same thing:

 auto* v1 = &x; 

becomes

 template<typename T> void func(T* param) 

Since x is int , then auto* == int* .
And auto* v2 = px; also int*

Now the third one has:

 auto* v3 = &px; 

It becomes int** , as you take the address of the pointer.

 template<typename T> void func(T** param) // ^^^ 

A convenient way to see the type of car is to use what others have mentioned, the typeid() function.
But I like to use <boost/type_index.hpp> to display the type correctly:

 #include <iostream> #include <boost/type_index.hpp> using namespace std; using namespace boost::typeindex; int main() { int x = 64; int* px = &x; auto* v1 = &x; auto* v2 = px; auto* v3 = &px; cout << type_id_with_cvr<decltype(v1)>().pretty_name() << '\n'; cout << type_id_with_cvr<decltype(v2)>().pretty_name() << '\n'; cout << type_id_with_cvr<decltype(v3)>().pretty_name() << '\n'; } 

What outputs:

 int* int* int** 

There is one important difference between automatic type deduction and template type inference, namely std::initializer_list<>

Consider the following examples:

 auto i = 1; // int auto j(1); // int auto k = { 1 }// std::initializer_list<int> ! auto l { 1 } // std::initializer_list<int> ! 

As you can see, using a combination initializer with a car can be a problem.
However, you can manually write the type in front of curly braces to make sure the type is correct, but I don’t see the point:

 auto i = int{ 1 }; // type is int 

There are new automatic rules that are already implemented in Clang 3.8, which allows you to use direct list initialization with auto (upcoming standard)

+1
source

auto will output to the cv-qualification type of the specified expression. auto* will output to a cv-qualified expression type an expression of type to - if the expression is a pointer - and otherwise will not compile.

For the given examples, the actual type of v will be pointer to int , the same with v2 , and for v3 it will be pointer to pointer to int .

If your first example is written as auto v1 = &px , type v1 will remain the same.

+3
source

You can use typeid to answer your question.

 #include <iostream> #include <typeinfo> using namespace std; int main() { // your code goes here int x = 64; int* px = &x; auto* v1 = &x; auto* v2 = px; auto* v3 = &px; cout<<typeid(v1).name()<<endl; cout<<typeid(v2).name()<<endl; cout<<typeid(v3).name()<<endl; return 0; } 

Output:

 Pi Pi PPi 

Pi -> pointer to an integer variable

PPi -> pointer to an integer variable

+3
source

The output process matches the template parameter. If I do this:

 int a = 0; auto* b = &a; 

Type b will be int* . And write:

 auto b = &a; 

The result is the same int* type. In your example, the compiler will somehow add the missing star. But the simplest form would be to simply write auto

0
source

Source: https://habr.com/ru/post/1270534/


All Articles