您自己的类型的结构化绑定,不是结构或元组(通过公共成员函数)
Structured bindings for your own type that isn’t a struct or a tuple(via public member function)
我正在通过Herb Sutter的
旅程:迈向更强大、更简单的C++编程
结构绑定部分
为了理解这个概念.最好是编写一个我尝试过但出现一些错误的程序
只是想尝试如何在类上使用结构绑定与私有 数据。请忽略以下示例。如果您可以提供任何示例
#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;
}
错误
如果 constexpr(I == 0( 返回 x._ival;//'_ival' 是私有成员 的"福巴">
else if constexpr(I == 1( 返回 x.s;//'s' 是 'foobar' 的私有成员
auto [ n, s] = f( 1024,"hello" (;//无法分解非公共
需要帮助
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.如何解决上述示例错误的任何建议
这里有很多问题。
首先,为了有资格使用结构化绑定,您需要专门研究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; };
}
接下来,如果要像往常一样访问私有成员,则必须将get
声明为friend
函数:
class foobar {
template <int I> friend auto get(foobar const& );
};
最后,get()
确实有更好的返回引用,否则你的绑定最终会做一些令人惊讶的事情:
template<int I>
auto const& get(const foobar&x) {
if constexpr(I == 0) return x._ival;
else if constexpr(I == 1) return x.s;
}
与其处理friend
船,不如将get()
设为公共成员,然后编写所需的三个重载:
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()
作为一个函数也没有意义。你的构造函数应该只接受参数。
修复萨特示例中的错误
我认为这是赫伯·萨特(Herb Sutter(博客文章中的错字/故障:他应该公开这些成员,或者为他们提供getter,或者让std::get()
功能成为朋友。
另外,看起来赫伯忘记在函数签名中输入"x"......
获取函数的说明
您引用的函数类似于元组的std::get()
工作方式。如果我有
std::tuple<int, std::string> t;
然后
auto x { std::get<0>(t) }; // x is an integer
auto y { std::get<1>(t) }; // y is an std::string
在 Herb 的例子中,他需要对S
类进行相同的工作,即std::get<0>(s)
返回s
的第一个成员,std::get<1>(s)
返回第二个成员等。这是必需的,因为否则,不能使用S
初始化结构化绑定。
Hebr 实现中的"魔力"在于他从函数中的不同点返回不同类型的值。这种"魔法"是if constexpr
的效果。从本质上讲,这意味着编译器忽略了除不相关分支的语法之外的所有内容。所以对于I = 0
,函数是:
auto get(const S&) {
if (true) return x.i;
/* else if constexpr(I == 1) return string_view{x.c};
else if constexpr(I == 2) return x.d;
*/
}
对于I = 1
来说,它是
template<int I>
auto get(const S&) {
if (false) {/* return x.i; */ ; }
else if (true) return string_view{x.c};
/* else if constexpr(I == 2) return x.d; */
}
}
等。auto
选择适当的类型。
- 访问和打印元组中的数据,并使用 C++14 使用模板函数显示数据
- 如何在可变参数模板函数中遍历可变参数元组?
- 提升精神 QI:在元组上自动规则演绎,在替代函数中带有序列
- 使用函数的元组返回多个值的问题
- 将函数应用于元组中的每个元素,将每个元素强制转换为类型包中的不同类型,然后作为参数包传递
- 从函数的可变参数构建特定元组
- 您自己的类型的结构化绑定,不是结构或元组(通过公共成员函数)
- 从函数返回元组时,将复制元组的参数,而不是移动元组参数
- 从可调用可变参数元组中的函数结果创建元组
- 从类型元组到通过调用模板函数返回的值数组
- 为模板中的元组创建递归函数
- 如何为返回枚举元组的 C++ 函数编写 cython 包装器?
- 元组尺寸默认构造函数及其转换为std :: size_t
- 使用单参数模板化构造函数,从引用元组构造值元组
- 在函数呼叫时,请从异质初始化列表中构建元组
- 带有映射的 Lambda 函数,其中键是元组,值是双精度
- CPP 元编程:包含元组函数
- 如何编写对转发的引用元组进行操作的constexpr函数
- 将函数的返回值存储在元组中
- 将一系列元组解压缩为 n 元函数