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
S
class, 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 useS
for 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 = 1
it'setc. And the
auto
chooses the appropriate type.