C++17 Snippets: Making code clearer with Auto Template Parameter Type Deduction

This article simply focuses on how to make code clearer when creating tuples, pairs and vectors.

In c++14, if you wanted to use tuple, you could construct one with the make_tuple function. This would save you from having to explicitly declare the types as template arguments.



#include <tuple>
#include <iostream>

using namespace std;

int main(){ 

    //explicit template arguments to specify types
    auto p = tuple<int, string, float>(5, "yes", 4.0f);

    //using make tuple to clean it up a bit  
    auto q = make_tuple(5, "yes", 4.0f);

    //use uniform initialization
    auto r = tuple<int, string, float>{5, "yes", 4.0f};

    //print it using horrible get<> syntax, yuck 
    cout << get<0>(p) << get<1>(p) << get<2>(p) << endl; 

    return 0; 

}

Now in c++17 you can just pass the arguments into the initialization list and the types that go in the angle brackets are deduced which make it look a bit nicer.

#include <tuple>
#include <iostream>

using namespace std; 

int main(){ 

    //template arguments deduced. nicer. 
    auto p = tuple{5, "yes", 4.0f}; 

    //print it using horrible get<> syntax, yuck 
    cout << get<0>(p) << get<1>(p) << get<2>(p) << endl; 

    return 0; 
}

This works for tuple and pair! You can actually write these variable declarations two ways…

pair p{2, 4.5f};

or

auto p = pair{2, 4.5f}; 

It’s up to you which style you would like to use.

pair p{2, 4.5f};      //deduced as pair<int, float>
pair q{2, 4.5};       //deduced as pair<int, double>
tuple t{4, 3, 2.5}; //deduced as tuple<int, int, double>

The (…) vs {…} debate

This c++17 features takes away the need for make_pair and make_tuple. One could argue that using those makes it clear the intent of what is happening. There are guidelines that say that initialization with curly {…} braces are clearer.

This also works for vectors…..

vector v{3,5};

or

auto v = vector{3,5};

which is definitely nicer.

So here are my closing thoughts…

We have two ways of doing the same thing. Use auto and assign or state the variable type first. I prefer the latter which is….

vector v{3,5};

auto should probably be used only when returning from a function. This was useful when we had make_pair() and make_tuple() but now we can state the variables directly.

 

Also look at how this….

list<tuple<string,string>> il{
    tuple<string,string>{"Maya","Meh"},
    tuple<string,string>{"Houdini","Awesome!"},
    tuple<string,string>{"Katana","?"}
};

vector<tuple<string,string>> vec{
    tuple<string,string>{"Maya","Meh"},
    tuple<string,string>{"Houdini","Awesome!"},
    tuple<string,string>{"Katana","?"}
};

…turns to this….

list il{
    tuple{"Maya","Meh"},
    tuple{"Houdini","Awesome!"},
    tuple{"Katana","?"}
};

vector vec{
    tuple{"Maya","Meh"},
    tuple{"Houdini","Awesome!"},
    tuple{"Katana","?"}
};

Inside c++ is the scripting language that we all want trying to get out!

Happy coding!

Leave a Comment