I have C++ code with a type auto:
auto T = reads a JSON
I need to print the content of the T using
cout << T << endl;
It is not working. Can you help me?
With C++11, you can declare a variable or an object without specifying its specific type by using auto.1 For example:
auto i = 42; // i has type int
double f();
auto d = f(); // d has type double
The type of a variable declared with auto is deduced from its initializer. Thus, an initialization is required:
auto i; // ERROR: can’t dedulce the type of i
Additional qualifiers are allowed. For example:
static auto vat = 0.19;
Using auto is especially useful where the type is a pretty long and/or complicated expression. For example:
vector<string> v; ... auto pos = v.begin(); // pos has type vector<string>::iterator
auto l = [] (int x) -> bool { // l has the type of a lambda ..., // taking an int and returning a bool };
In short auto can deduce any type .Your program is not working because it is possible that it is not able to parse JSON or compiler is old (where auto is not supported .Can you specifically let me know the error you got ?
auto in C++ means "set variable type for type of initialization expression", in your case whatever that "reads a JSON" expression returns. You cannot output that type to std::cout because operator<< is not defined for such type, there could be many possible reasons as operator not provided, you suppose to use something else, missing header etc. Solution would depend on actual type.
Ok ! Before telling you how to use auto, I must tell you it's one of the best features of C++11 & has made C++ even more efficient by :-
Reducing amount of code
Enforcing initialization
Increasing genericity (In C++17)
Firstly auto has only 1 job. It will deduce the type of an object by the value passed to it. For ex :-
auto x = 5;
This means that x is an integer whose value is 5. Whenever you are using auto you must initialize the variable (which is a good thing) & you cannot use auto on multiple types in a statement. For ex :-
auto x; // illegal ! x isn't initialized so compiler cannot dduce it's type
auto z=5, y=7; // legal because z & y are both integers
auto a=8, ch= 'c'; // illegal ! an integer & a character in a single statement, hence type deduction ambiguity
The cream of auto is not in intializing int, char, etc data types. It's more handy for classes like iterators. For ex :-
vector<int> v;
vector<int>::iterator i1 = v.begin();
auto i2 = v.begin(); // see how auto reduces the code length
This can be even more obvious in for loops :-
for (vector<int>::iterator i = v.begin(); i!=v.end(); ++i);
Can be reduced to :-
for (auto i = v.begin(), i!=v.end(); ++i);
If you are not happy with the above then this may inspire you to use auto :-
vector< map <int, vector<string> > >::iterator i1 = v.begin(); // where v is the vector of maps of ints & vectors of strings !!!!
auto i2 = v.begin();
The genericity I was talking about is in passing values to functions by auto. Like :-
void add (auto x, auto y)
{
cout << x+y << '\n';
}
This is not possible in current standards & has been proposed for C++17. This is likely to increase the generic ability of the functions without the use of templates. However this syntax is possible for lambda functions :-
auto l = [](auto x, auto y) { return x+y; } // legal from C++14 onwards
However be careful when using braces with lambda because you may think that :-
auto x = {5};
Is an integer but it is actually an intializer_list<int> type object. I can explain a hell lot about auto but I guess for now this is more than enough.
Related
C++17 standard introduces a new structured bindings feature, which was initially proposed in 2015 and whose syntactic appearance was widely discussed later.
Some uses for them come to mind as soon as you look through documentation.
Aggregates decomposition
Let's declare a tuple:
std::tuple<int, std::string> t(42, "foo");
Named elementwise copies may be easily obtained with structured bindings in one line:
auto [i, s] = t;
which is equivalent to:
auto i = std::get<0>(t);
auto s = std::get<1>(t);
or
int i;
std::string s;
std::tie(i, s) = t;
References to tuple elements can also be obtained painlessly:
auto& [ir, sr] = t;
const auto& [icr, scr] = t;
So we can do with arrays or structs/classes whose all members are public.
Multiple return values
A convenient way to get multiple return values from a function immediately follows from the above.
What else?
Can you provide some other, possibly less obvious use cases for structured bindings? How else can they improve readability or even performance of C++ code?
Notes
As it were mentioned in comments, current implementation of structured bindings lacks some features. They are non-variadic and their syntax does not allow to skip aggregate members explicitly. Here one can find a discussion about variadicity.
Can you provide some other, possibly less obvious use cases for structured bindings? How else can they improve readability or even performance of C++ code?
More in general, you can use it to (let me say) unpack a structure and fill a set of variables out of it:
struct S { int x = 0; int y = 1; };
int main() {
S s{};
auto [ x, y ] = s;
(void)x, void(y);
}
The other way around would have been:
struct S { int x = 0; int y = 1; };
int main() {
S s{};
auto x = s.x;
auto y = s.y;
(void)x, void(y);
}
The same is possible with arrays:
int main() {
const int a[2] = { 0, 1 };
auto [ x, y ] = a;
(void)x, void(y);
}
Anyway, for it works also when you return the structure or the array from a function, probably you can argue that these examples belong to the same set of cases you already mentioned.
Another good example mentioned in the comments to the answer by #TobiasRibizel is the possibility to iterate through containers and unpack easily the contents.
As an example based on std::map:
#include <map>
#include <iostream>
int main() {
std::map<int, int> m = {{ 0, 1 }, { 2, 3 }};
for(auto &[key, value]: m) {
std::cout << key << ": " << value << std::endl;
}
}
Can you provide some other, possibly less obvious use cases for structured bindings?
They can be used to implement get<N> for structs - see magic_get's automatically generated core17_generated.hpp. This is useful because it provides a primitive form of static reflection (e.g. iterate over all members of a struct).
Initializing multiple variables of different types in an if statement; for instance,
if (auto&& [a, b] = std::pair { std::string { "how" }, 4U }; a.length() < b)
std::cout << (a += " convenient!") << '\n';
Barring evidence to the contrary, I think Structured Bindings are merely a vehicle to deal with legacy API. IMHO, the APIs which require SB should have been fixed instead.
So, instead of
auto p = map.equal_range(k);
for (auto it = p.first; it != p.second; ++it)
doSomethingWith(it->first, it->second);
we should be able to write
for (auto &e : map.equal_range(k))
doSomethingWith(e.key, e.value);
Instead of
auto r = map.insert({k, v});
if (!r.second)
*r.first = v;
we should be able to write
auto r = map.insert({k, v});
if (!r)
r = v;
etc.
Sure, someone will find a clever use at some point, but to me, after a year of knowing about them, they are still an unsolved mystery. Esp. since the paper is co-authored by Bjarne, who's not usually known for introducing features that have such a narrow applicability.
I'm relatively new to C++. I just read about the auto keyword in regards to type deduction. I've tried implementing this in a couple functions only to find that it was causing all of kinds of issues when working with math operators. I believe what was happening was that my functions started implementing integer division when I actually needed float division (variables 'i' and 'avg'). I posted the code using the auto keywords below.
Now when I explicitly declared the variables as floats, the function worked fine.
So is this an example in which using auto would not be preferred? However, I can definitely see that they would help when generating the iterators.
namespace Probability
{
/* ExpectedValueDataSet - Calculates the expected value of a data set */
template <typename T, std::size_t N>
double ExpectedValueDataSet(const std::array<T, N>& data)
{
auto i = 0;
auto avg = 0;
for(auto it = data.begin(); it != data.end(); it++)
{
i = it - data.begin() + 1;
avg = ((i-1)/i)*avg + (*it)/i;
}
std::cout << avg << " \n";
return avg;
}
};
The literal 0 is of type int.
A variable auto avg = 0; therefore has type int.
The literal 0.0 (or e.g. 3.14) has type double, which is what you want.
As a general rule, use auto for a variable declaration where
the type is explicitly specified in the initializer, or
the type is awfully verbose, like some iterator type.
But don't use it without reason. :)
If for e.g. aesthetic reasons you want to keep i as an integer, then rewrite the computation
((i-1)/i)*avg + (*it)/i
to e.g.
((i-1)*avg + *it)/i
to avoid pure integer arithmetic for (i-1)/i.
I have a vector with each element being a pair. I am confused with the syntax. Can someone please tell me how to iterate over each vector and in turn each element of pair to access the class.
std::vector<std::pair<MyClass *, MyClass *>> VectorOfPairs;
Also, please note, I will be passing the values in between the function, hence VectorOfPairs with be passed by pointer that is *VectorOfPairs in some places of my code.
Appreciate your help. Thanks
This should work (assuming you have a C++11 compatible compiler)
for ( auto it = VectorOfPairs.begin(); it != VectorOfPairs.end(); it++ )
{
// To get hold of the class pointers:
auto pClass1 = it->first;
auto pClass2 = it->second;
}
If you don't have auto you'll have to use std::vector<std::pair<MyClass *, MyClass *>>::iterator instead.
Here is a sample. Note I'm using a typedef to alias that long, ugly typename:
typedef std::vector<std::pair<MyClass*, MyClass*> > MyClassPairs;
for( MyClassPairs::iterator it = VectorOfPairs.begin(); it != VectorOfPairs.end(); ++it )
{
MyClass* p_a = it->first;
MyClass* p_b = it->second;
}
Yet another option if you have a C++11 compliant compiler is using range based for loops
for( auto const& v : VectorOfPairs ) {
// v is a reference to a vector element
v.first->foo();
v.second->bar();
}
You can access the elements of pairs inside vector in C++17 in a following style by combining range-based for loop and structured bindings. Example:
for (auto& [x, y] : pts) {
cin >> x >> y;
}
where pts is a vector of pairs. & is used to make formal "uniquely-named variable" e of structured binding a reference so that x and y referring to subobjects of e refer to original pair inside pts, which can be modified this way (e.g. cin can be used to input to it). Without &, e would be a copy (to subobjects of which x and y again refer). Example using your VectorOfPairs:
for (auto [pFirst, pSecond] : VectorOfPairs ) {
// ...
}
Also you can make e a reference to const when modification through structured binding is not needed and you want to avoid potentially expensive copy of a pair (though this should not be a problem in your case since pair object consisting of 2 pointers is pretty small and cheap to copy). Example:
for (const auto& [pFirst, pSecond] : VectorOfPairs ) {
// ...
}
The book i am reading offers this example when iterating over a vector
for (auto &e: v) {
cout << e << endl;
}
Suppose v is declared as vector<int> v, in other words, we know that the type of elements inside this collection is int.
Is using auto in any way better or preferred to?
for (int &e: v) {
cout << e << endl;
}
Why?
Yes. auto is preferred. Because if you change the declaration ofv from:
std::vector<int> v; //before
to this:
std::vector<float> v; //after
If you use int & in the for, then you have to change that as well. But with auto, no need to change!
In my opinion, working with auto is more or less like programming to interface. So if you do an operation += in the loop, and you don't really care about the type of the loop variable e as long as the type supports += operation, then auto is the solution:
for(auto & e : v)
{
e += 2;
}
In this example, all you care about that the type of e supports += with int on the right hand side. It will work even for user-defined types, which has defined operator+=(int), or operator+=(T) where T is a type which supports implicit conversion from int . It is as if you're programming to interface:
std::vector<Animal*> animals;
animals.push_back(new Dog());
animals.push_back(new Cat());
animals.push_back(new Horse());
for(size_t i = 0 ; i < animals.size(); ++i)
{
animals[i]->eat(food); //program to interface
}
Of course, you would like to write this loop as:
for(Animal * animal : animals)
{
animal->eat(food); //still program to interface
}
Or simply this:
for(auto animal : animals)
{
animal->eat(food); //still program to interface
}
It is still programming to interface.
But at the same time, the point in #David's comment is worth noting.
On your first example, you have less dependency on what the elements of the vector are.
Suppose that in a month, you require that your vector stores larger integers, so you will have to use an std::vector<int64_t>, or some other, wider type. Now all of the code that iterates over that vector is invalid. You'll have to modify each:
for (int &e: v) {}
For a:
for (int64_t &e: v) {}
That is why it's better to just let auto deduce the internal type. That way you can modify the type stored in your vector for another, compatible one, and all your code will still work.
How is auto implemented in C++11? I tried following and it works in C++11
auto a = 1;
// auto = double
auto b = 3.14159;
// auto = vector<wstring>::iterator
vector<wstring> myStrings;
auto c = myStrings.begin();
// auto = vector<vector<char> >::iterator
vector<vector<char> > myCharacterGrid;
auto d = myCharacterGrid.begin();
// auto = (int *)
auto e = new int[5];
// auto = double
auto f = floor(b);
I want to check how this can be achieved using plain C++
It does roughly the same thing as it would use for type deduction in a function template, so for example:
auto x = 1;
does kind of the same sort of thing as:
template <class T>
T function(T x) { return input; }
function(1);
The compiler has to figure out the type of the expression you pass as the parameter, and from it instantiate the function template with the appropriate type. If we start from this, then decltype is basically giving us what would be T in this template, and auto is giving us what would be x in this template.
I suspect the similarity to template type deduction made it much easier for the committee to accept auto and decltype into the language -- they basically just add new ways of accessing the type deduction that's already needed for function templates.
In C++, every expression has value and type. For example, (4+5*2) is an expression which has value equal to 14 and type is int. So when you write this:
auto v = (4+5*2);
the compiler detects the type of the expression on the right side, and replaces auto with the detected type (with some exception, read comments), and it becomes:
int v = (4+5*2); //or simply : int v = 14;
Similarly,
auto b = 3.14159; //becomes double b = 3.14159;
auto e = new int[5]; //becomes int* e = new int[5];
and so on
The auto keyword is simply a way to declare a variable while having it type being based upon the value.
So your
auto b = 3.14159;
Will know that b is a double.
For additional reading on auto take a look at the following references
C++ Little Wonders: The C++11 auto keyword redux
The C++0x auto keyword
It works like before :)
Have you never hit a compiler error telling you:
error: invalid conversion from const char* to int
for such a code fragment: int i = "4";
Well, auto simply leverages the fact that the compiler knows the type of the expression on the right hand side of the = sign and reuses it to type the variable you declare.