标签: structured-bindings

基于范围的for循环on unordered_map和引用

在std :: unordered_map上运行基于范围的for循环时,似乎循环变量的类型不使用引用类型:

std::unordered_map<int, int> map = { {0, 1}, {1, 2}, {2, 3} };
for(auto&[l, r] : map)
    static_assert(std::is_same_v<decltype(r), int&>);
Run Code Online (Sandbox Code Playgroud)

MSVC 2017,gcc 8.2和clang 7.0.0都报告了一个失败的断言.将此反对到std :: vector,其中断言不会失败,正如人们所期望的那样:

std::vector<int> vec = { 1, 2, 3 };
for(auto& r : vec)
    static_assert(std::is_same_v<decltype(r), int&>);
Run Code Online (Sandbox Code Playgroud)

然而,在MSVC 2017和gcc 8.2上,修改局部变量r的循环将具有可观察到的副作用:

#include <iostream>
#include <type_traits>
#include <unordered_map>
#include <vector>

int main() {
    std::unordered_map<int, int> a = { {0, 1}, {1, 2}, {2, 3} };
    for(auto[l, r] : a)
        std::cout << l << "; " << …
Run Code Online (Sandbox Code Playgroud)

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

14
推荐指数
1
解决办法
796
查看次数

为什么结构化绑定依赖于tuple_element?

最新草稿结构化绑定提案(在其上的C++ 17特征是基于)的要求std::tuple_size,构件getstd::get,和std::tuple_element.以前的草稿只需要std::tuple_size和成员getstd::get.据我所知,没有讨论增加这一点,它只是出现在最终草案中.是否有令人信服的理由要求tuple_element专业化,考虑到我认为它可以作为一般实施

template<std::size_t index, typename T>
struct tuple_element {
    using type = decltype(std::get<index>(std::declval<T>()));
};
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么要添加此要求?

c++ c++17 structured-bindings

13
推荐指数
1
解决办法
388
查看次数

为什么结构化绑定在struct上不能按预期工作?

struct X { int a, b; };

int main()
{
    auto p = std::pair{ 1, 2 };
    const auto&[r1, r2] = p; // ok

    X x{ 1, 2 };
    const auto&[r3, r4] = x; // error
}
Run Code Online (Sandbox Code Playgroud)

clang 7.0(在Windows上)的错误信息:

error : cannot decompose this type; 'std::tuple_size<const X>::value' is not a valid 
           integral constant expression
Run Code Online (Sandbox Code Playgroud)

为什么结构化绑定在struct上不能按预期工作?

c++ standards alias c++17 structured-bindings

13
推荐指数
1
解决办法
880
查看次数

为什么基于范围的for-loop中的结构化绑定只是一个副本而不是一个引用?

我有以下代码:

#include "stdafx.h"
#include <unordered_map>
#include <cassert>
int main()
{
    struct Foo { int a; };
    std::unordered_map<int, Foo> foos{ { 0, { 3 } }, { 1, { 4 } } };
    for (auto &[i, foo] : foos)
    {
        foo.a = 6; //doesn't change foos[i].a
        assert(&foo.a == &foos[i].a); //does not pass
    }

    auto &[i, foo] = *foos.begin();
    foo.a = 7; //changes foo[0].a
    assert(&foo.a == &foos[0].a); //passes
}
Run Code Online (Sandbox Code Playgroud)

我的问题:

为什么第一个断言语句在第二个传递时没有通过?为什么我不能改变的价值foofoos地图中基于范围循环?

编译: MSVS ++ 17 Visual studio 15.3.2 …

c++ for-loop visual-c++ c++17 structured-bindings

12
推荐指数
1
解决办法
3102
查看次数

如果结构化绑定不能是constexpr,为什么它们可以在constexpr函数中使用?

根据这个答案,显然没有充分的理由说明为什么不允许结构化绑定是constexpr,但标准仍然禁止它.但是,在这种情况下,是否应该禁止在constexpr函数中使用结构化绑定?考虑一个简单的片段:

#include <utility>

constexpr int foo(std::pair<int, int> p) {
    auto [a, b] = p;
    return a;
}

int main() {
    constexpr int a = foo({1, 2});
    static_assert(a == 1);
}
Run Code Online (Sandbox Code Playgroud)

无论GCC不惹麻烦编译代码.代码是否格式不正确或实际允许这个?

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

12
推荐指数
1
解决办法
815
查看次数

为什么auto在使用结构化绑定时似乎会推断出引用?

请考虑以下使用C++ 17结构化绑定的代码:

int a = 0, b = 0;
auto [x, y] = std::tie(a, b);
y = 1;
std::cout << a << ' ' << b << '\n';
Run Code Online (Sandbox Code Playgroud)

由于我使用auto,我希望的代码打印0 0y应该是一个拷贝.然而,它打印0 1.为什么?我认为裸露auto从不推断参考.

c++ c++17 structured-bindings

12
推荐指数
1
解决办法
587
查看次数

在const上的结构化绑定

以下代码应该编译吗?

#include <type_traits>

void foo() {
  const std::pair<int, int> x = {1, 2};

  auto [a, b] = x;

  static_assert(std::is_const_v<decltype(a)>);
  static_assert(std::is_const_v<decltype(b)>);
}
Run Code Online (Sandbox Code Playgroud)

那么,这是MSVC错误吗?

该标准是不是直接在这里(我有一个快速浏览一下),但考虑规则auto,我想,a并且b应该被复制丢弃CV-预选赛

c++ c++17 structured-bindings

11
推荐指数
2
解决办法
370
查看次数

结构化绑定和基于范围的; 在gcc中抑制未使用的警告

我想使用结构绑定遍历地图,忽略键:

for (auto& [unused, val] : my_map)
     do_something(val);
Run Code Online (Sandbox Code Playgroud)

我尝试过gcc-7.2.0的不同选项:

// The warning is issued
for ([[maybe_unused]] auto& [unused, val] : my_map)
      do_something(val);

// Syntax error
for (auto& [[[maybe_unused]] unused, val] : my_map)
      do_something(val);

// The same two combinations above with [[gnu::unused]].
Run Code Online (Sandbox Code Playgroud)

似乎该[[maybe_unused]]属性尚未实现结构绑定.

这有什么简单的解决方案吗?任何宏,gcc/gnu扩展名,或任何暂时禁止该特定警告的pragma对我来说都没有问题; 例如,在我使用基于范围的for的整个函数体中禁用它,因为我使用它的函数非常短(它基本上是两个不同映射的两个范围,具有精确的行为).

我用来编译项目的(相关)选项是:

-std=c++17 -Wall -Wextra -Werror -pedantic -pedantic-errors
Run Code Online (Sandbox Code Playgroud)

我目前要做的是,但这很难看:

for (auto& [unused, val] : my_map)
   (void)unused, do_something(val);
Run Code Online (Sandbox Code Playgroud)

c++ gcc unused-variables c++17 structured-bindings

10
推荐指数
2
解决办法
1067
查看次数

结构化绑定和领带()

鉴于这些声明:

int a[3] {10,20,30};
std::tuple<int,int,int> b {11,22,33};
Run Code Online (Sandbox Code Playgroud)

我可以使用结构化绑定声明来解码ab:

auto [x1,y1,z1] = a;
auto [x2,y2,z2] = b;
Run Code Online (Sandbox Code Playgroud)

但是,如果x1,y1等已经存在了,我该怎么办?

std::tie(x1,y1,z1) = a;  // ERROR
std::tie(x2,y2,z2) = b;  // OK
Run Code Online (Sandbox Code Playgroud)

这适用b但不适用a.是否有一个类似的简单构造,对工作a,还是我去取a[0],a[1]a[2]分别?

c++ c++17 structured-bindings

10
推荐指数
1
解决办法
701
查看次数

lambda 参数中的结构化绑定

为什么在这种情况下我不能使用 C++17 结构化绑定?

std::map<int, int> m;
std::find_if( m.cbegin(), m.cend(), []( const auto & [x, y] ){ return x == y; } );
Run Code Online (Sandbox Code Playgroud)

c++ c++17 structured-bindings

10
推荐指数
1
解决办法
956
查看次数