相关疑难解决方法(0)

结构化绑定的decltype(auto)应该是引用吗?

考虑一个例子:

#include <iostream>
#include <type_traits>
#include <tuple>

int main() {
    auto tup = std::make_tuple(1, 2);
    auto [ a, b ] = tup;
    decltype(auto) e = a;
    std::cout << std::boolalpha << std::is_reference_v<decltype(e)> << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

在这个简单的例子中,clang(输出:)falsegcc(输出:)true不一致.记住,例如这个Q&As应该e是一个参考还是一个gcc bug?或者代码可能不正确?

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

27
推荐指数
1
解决办法
696
查看次数

复制省略是否适用于结构化绑定

强制复制省略是否适用于通过结构化绑定进行分解?以下哪种情况适用于?

// one
auto [one, two] = std::array<SomeClass>{SomeClass{1}, SomeClass{2}};

// two
auto [one, two] = std::make_tuple(SomeClass{1}, SomeClass{2});

// three
struct Something { SomeClass one, two; };
auto [one, two] = Something{};    
Run Code Online (Sandbox Code Playgroud)

我怀疑只有第三种情况允许复制省略,因为前两个会被"分解"通过std::get<>std::tuple_size<>std::get<>当参数是右值返回xvalues

标准的引用也很好!

c++ rvalue copy-elision c++17 structured-bindings

16
推荐指数
1
解决办法
827
查看次数

基于范围的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
查看次数

在decltype(auto)的情况下,lambda是否有特殊规则?

如果我正确理解了这个答案并引用了标准部分[dcl.type.auto.deduct-5],那么代码如下:

decltype(auto) a = e;
Run Code Online (Sandbox Code Playgroud)

总是相当于

decltype( e  ) a = e;
Run Code Online (Sandbox Code Playgroud)

但是现在问题出现了,而不是e我把lambda表达式放到decltype(auto):

decltype(auto) lambda = [](){};
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,这在gccclang中成功编译.我所经历的冲击的原因在于标准,其中特别指出lambda不应出现在未评估的操作数中[expr.prim.lambda#2](强调我的):

lambda-expression是一个prvalue,其结果对象称为闭包对象.lambda表达式不应出现在未评估的操作数,模板参数,别名声明,typedef声明或函数体和默认参数之外的函数或函数模板的声明中.

但正如我所提到的,这个例子相当于:

decltype([](){}) lambda = [](){};
Run Code Online (Sandbox Code Playgroud)

明确写出的上述代码显然是不正确的.当然,我们可以假设[](){}里面的语句decltype是一种引用,实际上并不是像结构化绑定那样的引用,但是标准中有一条特殊的规则,我错过了覆盖lambda的初始化decltype(auto)

c++ lambda decltype language-lawyer c++14

11
推荐指数
1
解决办法
421
查看次数

结构化绑定在C++ 17中引入的标识符类型有哪些?

据我所知,C++ 17中结构化绑定引入的标识符实际上是对某些"隐藏"变量的引用.这样

auto [ a, b ] = std::make_tuple(1, 2);
Run Code Online (Sandbox Code Playgroud)

一种等同于

auto e = std::make_tuple(1, 2);
auto& a = std::get<0>(e);
auto& b = std::get<1>(e);
Run Code Online (Sandbox Code Playgroud)

但是,如果我打印出来std::is_reference<decltype(a)>::value,我会01第二种情况下进入第一种情况.这是为什么?

c++ reference decltype c++17 structured-bindings

9
推荐指数
1
解决办法
409
查看次数

结构化绑定中的变量类型

#include <type_traits>

int main()
{
    int arr[1] = { 6 };

    auto& ref1 = arr[0];  
    static_assert( std::is_same_v<decltype( ref1 ), int&> ); //ok

    auto& [ ref2 ] = arr;
    static_assert( std::is_same_v<decltype( ref2 ), int> ); //ok
    static_assert( std::is_same_v<decltype( ref2 ), int&> ); //error
}
Run Code Online (Sandbox Code Playgroud)

标识符ref1ref2该示例之间的重要区别是什么?据我所知,ref2在结构绑定中也有一个引用类型,但为什么要为它decltype指示一个非引用类型?

c++ decltype auto type-deduction c++17

9
推荐指数
1
解决办法
265
查看次数

在结构化绑定定义中引入了中间变量?

[dcl.struct.bind] 9.6.4中,当初始化器是正确定义的类类型时,有结构化绑定的定义std\xe2\x80\x8b::\xe2\x80\x8btuple_\xc2\xadsize<E>\xe2\x80\x8b::\xe2\x80\x8bvalue

\n
\n

...变量以唯一名称ri引入,如下所示:
\n S Ui ri = 初始值设定项 ;
\n每个vi都是Ti类型的左值的名称,该左值引用绑定到ri的对象;\n引用的类型是Ti

\n
\n

我的问题是为什么需要引入ri,我们不能直接定义标识符vi作为对结果的引用吗get<i>(e)

\n

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

8
推荐指数
1
解决办法
256
查看次数