One of the most iconic C++ features is the language’s ability to deduce types with the auto keyword. In this post, I’ll give a series of code snippits. Your job is to assess what will be deduced for v in each case. Determine for each:
Some of these may not even compile, so “this won’t work” is a totally valid answer.
Each section increases in difficulty. Good luck!
Basic assignments and deduction from constants and straightforward types.
int x;
auto v = x;
auto v = 5, w = 0.1;
int x;
auto v = &x;
auto v = { 1, 2, 3 };
Type: std::initializer_list<int>
int x[5];
auto v = x;
int foo(int x) {
return x;
}
auto v = foo;
Exploring how references and CV-qualifiers are handled.
volatile const int x = 1;
auto v = x;
volatile const int x = 1;
auto v = &x;
Type: volatile const int*
int x;
int& y = x;
auto v = y;
int x;
auto& v = x;
int x[5];
auto& v = x;
int foo(const int x) {
return x;
}
auto v = foo;
Forwarding references, decltype(auto), inheritance, structured binding, and lambdas.
int x;
auto&& v = x;
auto x = [] () -> int {
return 1;
};
auto&& v = x();
int x;
auto y = [&] () -> int& {
return x;
};
auto&& v = y();
int x;
decltype(auto) v = (x);
struct Foo {};
auto&& v = Foo{};
struct Foo {};
decltype(auto) v = Foo{};
int x;
decltype(auto) v = std::move(x);
int foo(int x) {
return x;
}
decltype(auto) v = foo;
int foo(int x) {
return x;
}
decltype(auto) v = (foo);
class Base {
public:
auto foo() {
return this;
};
};
class Derived : public Base {
};
Derived d;
auto v = d.foo();
Abandon all hope, ye who attempt to deduce the types of lambda captures in expressions with decltype(auto) and symbols defined via structured binding.
int x;
[&] {
decltype(auto) v = x;
}();
int x;
[&] {
decltype(auto) v = (x);
}();
int x;
[=] {
decltype(auto) v = x;
}();
int x;
[=] {
decltype(auto) v = (x);
}();
int x;
[=] mutable {
decltype(auto) v = (x);
}();
int x;
int& y = x;
[=] () {
decltype(auto) v = y;
}();
std::pair x {1, 2.0};
auto [v, w] = x;
Type: std::tuple_element<0, std::pair<int, float> >::type& (but which presents as an int in basically every observable way)
You can check any of these by using this GodBolt link. Shoutout to this Stack Overflow thread which provided the code snippit to print human readable names for a variable.
Do you have any interesting examples to share? Reach out at sam@volatileint.dev and let me know! If you found this article interesting, consider subscribing to the newsletter to hear about new posts!