I am going through the Herb Sutter's
A journey: Toward more powerful and simpler C++ programming
Structure Binding section
In order to understand the concept .Best is to write a program I tried but getting some error
Just want to try how to use structure binding on class with private data .Please ignore the below example.if any example you can provide
#include<iostream>
#include<string>
using namespace std;
class foobar {
public:
foobar() { cout << "foobar::foobar()\n"; }
~foobar() { cout << "foobar::~foobar()\n"; }
foobar( const foobar &rhs )
{ cout << "foobar::foobar( const foobar & )\n"; }
void ival( int nval, string new_string ) { _ival = nval;s=new_string; }
private:
int _ival;
string s;
};
foobar f( int val,string new_string ) {
foobar local;
local.ival( val,new_string );
return local;
}
template<> struct tuple_element<0,foobar> { using type = int; };
template<> struct tuple_element<1,foobar> { using type = string; };
// 2. Now add get<> support (using C++17, because why not; it’s better
// than =delete’ing the primary get<> template and adding specializations)
template<int I>
auto get(const foobar&x) {
if constexpr(I == 0) return x._ival;//'_ival' is a private member of 'foobar'
else if constexpr(I == 1) return x.s;//'s' is a private member of 'foobar'
}
int main(){
foobar ml = f( 1024,"hello" );
auto [ n, s] = f( 1024,"hello" );//Cannot decompose non-public member '_ival' o
return 0;
}
Error
if constexpr(I == 0) return x._ival;//'_ival' is a private member of 'foobar'
else if constexpr(I == 1) return x.s;//'s' is a private member of 'foobar'
auto [ n, s] = f( 1024,"hello" );//Cannot decompose non-public
Help required
1.If anyone can elaborate what he is actually trying to do on these lines (please refer the link provided)
// 2. Now add get<> support (using C++17, because why not; it’s better
// than =delete’ing the primary get<> template and adding specializations)
template<int I>
auto get(const S&) {
if constexpr(I == 0) return x.i;
else if constexpr(I == 1) return string_view{x.c}; }
else if constexpr(I == 2) return x.d;
}
2.Any suggestion how to fix the error for the above example
Fixing the errors in Sutter's example
I think it's a typo/glitch in Herb Sutter's blog post: He should have made those members public, or provided getters for them, or made the
std::get()function a friend.Also, it looks like Herb forgot to put "x" in the function signature...
Explanation of the get function
The function you quote is similar to how
std::get()works for tuples. If I havethen
and in Herb's example, he needs to have the same work for the
Sclass, i.e. havestd::get<0>(s)return the first member ofs,std::get<1>(s)return the second member etc. This is necessary, because otherwise, you can't useSfor initializing a structured binding.The "magic" in Hebr's implementation is that he's returning values of different types from different points in his function. This "magic" is the effect of an
if constexpr. It means, essentially, that the compiler ignores everything except the syntax of the irrelevant branches. So forI = 0, the function is:for
I = 1it'setc. And the
autochooses the appropriate type.