gpt4 book ai didi

c++ - 您自己的类型的结构化绑定(bind)不是结构或元组(通过公共(public)成员函数)

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:18:38 25 4
gpt4 key购买 nike

我正在浏览 Herb Sutter 的

旅程:走向更强大、更简单的 C++ 编程

Structure Binding

为了理解这个概念。最好是写一个我试过但出现一些错误的程序

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;
}

错误

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

需要帮助

1.如果有人能详细说明他在这些方面实际上想做什么(请引用提供的链接)

// 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.关于如何修复上述示例的错误的任何建议

最佳答案

这里有很多问题。

首先,为了符合结构化绑定(bind)的条件,您需要特化tuple_size:

namespace std {
template <> struct tuple_size<foobar> : std::integral_constant<size_t, 2> { };
}

接下来,您对 tuple_element 的特化也必须在 namespace std 中:

namespace std {
template <> struct tuple_size<foobar> : std::integral_constant<size_t, 2> { };

template <> struct tuple_element<0,foobar> { using type = int; };
template <> struct tuple_element<1,foobar> { using type = std::string; };
}

接下来,如果您要像往常一样访问私有(private)成员,您的get 必须声明为friend 函数:

class foobar {
template <int I> friend auto get(foobar const& );
};

最后,get() 确实有更好的返回引用,否则你的绑定(bind)最终会做出令人惊讶的事情:

template<int I>
auto const& get(const foobar&x) {
if constexpr(I == 0) return x._ival;
else if constexpr(I == 1) return x.s;
}

与其处理 friendship,不如让 get() 成为公共(public)成员,然后编写您需要的三个重载:

class foobar {
public:
template <size_t I>
auto& get() & {
if constexpr (I == 0) return _ival;
else if constexpr (I == 1) return s;
}

template <size_t I>
auto const& get() const& {
if constexpr (I == 0) return _ival;
else if constexpr (I == 1) return s;
}

template <size_t I>
auto&& get() && {
if constexpr (I == 0) return std::move(_ival);
else if constexpr (I == 1) return std::move(s);
}
};

此外,ival() 作为函数也没有意义。您的构造函数应该只接受参数。

关于c++ - 您自己的类型的结构化绑定(bind)不是结构或元组(通过公共(public)成员函数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45898828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com