标签: structured-bindings

结构化绑定取代std :: tie滥用

在阅读这篇关于c ++ 17最终特性的摘要时,我对结构化绑定(强调我的)部分感到有些惊讶:

结构化绑定

到目前为止,有一种已知的技巧滥用std :: tie直接将元组或对分配给不同的变量,而不必手动处理结果类型.这是一个hack,并且变量必须存在,现在你可以声明变量并在一行中初始化它们:

auto [a,b,c] = getvalues();

需要大括号,getvalues返回一个元组.提案中没有提到std :: pair,因此不清楚它是否适用于在某些插入方法中由STL返回的pair.

我假设他们提到了这种用法 std::tie

int a,b,c;
std::tie(a,b,c) = std::make_tuple(1,2,3);
Run Code Online (Sandbox Code Playgroud)

我认为这是一种推荐的做法.

有人可以解释为什么他们将上述例子称为黑客攻击吗?

c++ stdtuple c++17 structured-bindings

7
推荐指数
3
解决办法
2001
查看次数

为类提供类似元组的结构化绑定访问

我正在尝试为类提供类似元组的结构化绑定访问.为简单起见,我将在本文的其余部分使用以下类:

struct Test
{
    int v = 42;
};
Run Code Online (Sandbox Code Playgroud)

(我知道这个类支持开箱即用的结构化绑定,但我们假设它没有.)

启用对成员的类似元组的访问Test,我们必须专门化std::tuple_size并且std::tuple_element:

namespace std
{

template<>
struct tuple_size<Test>
{
    static const std::size_t value = 1;
};

template<std::size_t I>
struct tuple_element<I, Test>
{
    using type = int;
};

}
Run Code Online (Sandbox Code Playgroud)

而我们需要的最后一部分是要么Test::get<i>或函数get<i>(Test)Test的命名空间.让我们实现后者:

template<std::size_t I>
int get(Test t)
{
    return t.v;
}
Run Code Online (Sandbox Code Playgroud)

这有效.但是,我想返回对Test成员的引用std::get(std::tuple),例如,就像.因此,我实现get如下:

template<std::size_t I>
int& get(Test& t)
{
    return t.v;
}

template<std::size_t I> …
Run Code Online (Sandbox Code Playgroud)

c++ c++17 structured-bindings

7
推荐指数
1
解决办法
523
查看次数

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

我正在经历Herb Scutter的

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

结构绑定部分

为了理解这个概念.Best是编写一个我试过的程序,但是遇到了一些错误

只是想尝试如何在类上使用私有数据的结构绑定.请忽略下面的示例.如果您能提供任何示例

#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 …
Run Code Online (Sandbox Code Playgroud)

c++ stdtuple c++17 structured-bindings if-constexpr

7
推荐指数
2
解决办法
1553
查看次数

结构化数据成员的decltype,使用结构化绑定

我有一个模板,该模板的类型可以在结构上绑定到两个别名(可以是一个元组,也可以是一个结构)。我需要别名指向的两个变量的类型。

template <typename T>
T obj;
// type of a/b in auto&& [a, b] = obj ?
Run Code Online (Sandbox Code Playgroud)

在实际使用结构化绑定之前,我需要知道类型:

template <typename S>
void fn(ranges::any_view<S> range_of_tuple_or_struct_or_pair) {

    last_from = std::numeric_limits<?????>::max();

    // ????? should be the type of from (or to, they should be the same types) of: 
    //     auto&& [from, to] = <range element>

    for (auto&& [from, to] : range_of_tuple_or_struct_or_pair) {
         if (from != last_from) {
             ...;
             last_from = from;
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

c++ structured-bindings

7
推荐指数
1
解决办法
91
查看次数

结构化绑定中的 cv 限定符传播

正如dcl.struct.bind中引用的那样,

让 cv 表示 decl-specifier-seq 中的 cv 限定符。

将 E 的非静态数据成员指定为 m 0 、 m 1 、 m 2 、...(按声明顺序),每个 vi 是一个左值的名称,该左值引用 e 的成员 mi ,其类型为 cv T i ,其中 T i 是该成员的声明类型;

如果我理解正确,cv 限定符是从结构化绑定的声明中传播的。

假设我有一个简单的结构,

struct Foo {
    int x;
    double y;
};

Run Code Online (Sandbox Code Playgroud)

考虑两种情况,

const Foo f{1, 1.0};
auto& [x, y] = f;
// static_assert(std::is_same<decltype(x), int>::value); // Fails!
static_assert(std::is_same<decltype(x), const int>::value); // Succeeds
Run Code Online (Sandbox Code Playgroud)

现场演示。的 cv-qualifier 是否x来自扣除auto

第二个,

Foo f{1, 1.0};

const auto& [x, …
Run Code Online (Sandbox Code Playgroud)

c++ qualifiers language-lawyer c++17 structured-bindings

7
推荐指数
1
解决办法
166
查看次数

为什么在结构化绑定后不使用 std::move 就不能返回 std::unique_ptr ?

当我尝试编译以下代码时,出现错误 C2280。我猜编译器正在尝试复制 unique_ptr 或其他东西。

#include <memory>

std::pair<int, std::unique_ptr<int>> CreatePair()
{
    std::unique_ptr<int> my_int(new int);
    return { 1, std::move(my_int) };
}
std::unique_ptr<int> GetUinquePtr()
{
    auto [ignore, unique_ptr] = CreatePair();
    return unique_ptr; // <- Build error C2280 attempting to reference a deleted function
}
int main()
{
    auto unique_ptr = GetUinquePtr();
}
Run Code Online (Sandbox Code Playgroud)

完整的错误消息:

error C2280: 'std::unique_ptr<int,std::default_delete<int>>::unique_ptr(const std::unique_ptr<int,std::default_delete<int>> &)': attempting to reference a deleted function
Run Code Online (Sandbox Code Playgroud)

如果我添加 std::move() 它就会起作用:

std::unique_ptr<int> GetUinquePtr()
{
    auto [ignore, unique_ptr] = CreatePair();
    return std::move(unique_ptr); // <- This works
}
Run Code Online (Sandbox Code Playgroud)

如果我使用 …

c++ std unique-ptr structured-bindings

7
推荐指数
1
解决办法
474
查看次数

固定大小跨度的结构化绑定

在发现您可以符合人体工程学地将 s 转换 std::vector为固定大小的std::spans 后,我想我应该尝试以下结构化绑定std::vector

auto _ = std::vector{ 1,2,3 };
std::span<int, 3> a = std::span(_).first<3>();
auto [b,c,d] = a;
Run Code Online (Sandbox Code Playgroud)

但它不起作用https://godbolt.org/z/nhrYn65dW

然而,从P1024 std::span 的可用性增强看来这应该是合法的

添加对固定大小跨度的结构化绑定支持?一致同意

c++ structured-bindings c++20

7
推荐指数
1
解决办法
228
查看次数

结构化绑定宽度

是否可以使用结构化绑定语法确定在方括号中指定的变量名称数量,以匹配简单右侧的数据成员数量struct

我想创建通用库的一部分,它使用结构化绑定将任意类分解为其组成部分.目前没有可变版本的结构化绑定(并且,我认为,不能用于当前提出的语法),但我首先想到的是对一些函数进行一组重载decompose(),它将struct参数分解为一组成分.decompose()应该通过参数的数量(即struct数据成员)来重载.目前constexpr if 语法也可以用来发送它.但是,我如何sizeof...为上述目的模拟类似于运算符的东西?我不能auto [a, b, c]在SFINAE结构中的某处使用语法,因为它是一个分解声明和AFAIK任何声明都不能在里面使用decltype,我也不能在lambda函数体中使用它,因为lambda函数也不能在模板参数中使用.

当然我想拥有内置运算符(语法类似于sizeof[] S/ sizeof[](S)for class S),但是类似下面的东西也是可以接受的:

template< typename type, typename = void >
struct sizeof_struct
{

};

template< typename type >
struct sizeof_struct< type, std::void_t< decltype([] { auto && [p1] = std::declval< type >(); void(p1); }) > >
    : std::integral_constant< std::size_t, 1 >
{

};

template< typename type >
struct sizeof_struct< …
Run Code Online (Sandbox Code Playgroud)

c++ type-traits variadic-templates c++17 structured-bindings

6
推荐指数
1
解决办法
624
查看次数

lambda 捕获结构化绑定

据我了解,C++17 不禁止 lambda 表达式捕获结构化绑定。以下内容被 接受gcc但被拒绝clang,但cppreference声称 lambdas 无法捕获结构化绑定。

int arr[] {0, 1};
auto& [a, b] = arr;
auto foo = [&] { b = 9; }; // capturing structured bindings
Run Code Online (Sandbox Code Playgroud)
  1. 或者是clanggcc不符合的?

  2. cppreference 将行为标记为 C++17 的一部分是否错误?

c++ c++17 structured-bindings

6
推荐指数
0
解决办法
890
查看次数

为什么 MSVC 在结构化绑定中发现不合格的 get() ?

考虑以下代码:

#include <utility>
#include <type_traits>
#include <cstddef>
#include <iostream>

template <typename>
struct A
{
    void get() {}    // #1
};

template <typename ...Ts>
struct B : A<Ts>... {};

template <typename ...Ts>
struct std::tuple_size<B<Ts...>> : std::integral_constant<std::size_t, 2> {};

template <std::size_t I, typename ...Ts>
struct std::tuple_element<I, B<Ts...>>
{
    using type = int;
};

template <std::size_t I, typename ...Ts>
constexpr int get(B<Ts...>)    // #2
{
    return 2;
}

int main()
{
    B<double, long long> b;
    auto [x, y] = b;
    std::cout << x …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++17 structured-bindings

6
推荐指数
1
解决办法
188
查看次数