std::pair<int,float> foo();
auto [a,b] = foo();
it will replaces:
std::pair<int,float> foo();
int a;
float b;
std::tie(a,b) = foo();
in case you are running an obfuscated code contest this new swap can scrub up well (please don't try this at home):
std::tie(a,b) = std::make_pair(b,a);
The decomposition works with c array and std::array as well:
int a[4] = { 1, 2, 3, 4};
auto [b,c,d,e] = a;
std::array<int, 4> a;
auto [b,c,d,e] = a;
and this is what you can do using a ranged for loop:
std::map myMap;
...
for (const auto & [k,v] : myMap) {
}
I bet someone in c++ committee has become recently a python enthusiast.
Now if you wonder what your structures like this:
stuct X {
int theInt = 3;
float thePi = 3.14;
};
auto [a,b] = x;
shall provide to make the decomposition working the response is: a plain nothing. That will work indeed off the shelf.Unfortunately if you need to do something more fancy with your class it has to support the get<>() functions, and you need to reopen the std namespace to specialize std::tuple_size and std::tuple_element.
Given the following user defined type (note a and b here are private members):
class Y {
public:
int foo() const {
return a;
}
float bar() const {
return b;
}
private:
int a = 3;
float b = 3.14;
};
you need to provide the gets<>() functions:
template <int N> auto get(Y const &);
template <> auto get<0>(Y const & aY) {
return aY.foo();
}
template <> auto get<1>(Y const & aY) {
return aY.bar();
}
and then you need to reopen the std namespace (one of those few allowed cases):
namespace std {
template<>
struct std::tuple_size<Y> {
static const size_t value = 2;
};
template<size_t I>
struct std::tuple_element<I, Y> {
using type = decltype(get<I>(declval<Y>()));
};
}
Note the partial specialization for std::tuple_element, you don't need to hard code the type of each index, it's enough to "deduce" it using the get function. You did a lot of work in order to have your class supporting the decomposition, in this case c++17 can save you some work taking advantage of a new c++17 feature, the "constexpr if", just writing a single version of get<>():
template<int N>
auto get(Y const & aY) {
static_assert(N==0 || N==1);
if constexpr (N == 0) {
return aY.foo();
} else if constexpr (N == 1) {
return aY.bar();
}
}
If you want use/experiment with those new language features go for clang++ (I tried only version 5.0 but it should work with the 4.0 as well) and you need to specify -std=gnu++1z