问题标签 [universal-reference]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
48 浏览

c++ - 通用引用产生具有相同地址的不同实例

我正在试验受Scott Meyers 关于该主题的文章启发的通用参考。

所以我尝试了以下方法:

输出:

我的印象是&j == &k可以保证j==k

这里发生了什么?

编辑,发布答案:

轶事反思:在第二次打印输出中输出 j 而不是 k 会使程序根本不输出任何内容。我想我应该很高兴没有切斯特菲尔德沙发或鲸鱼。

0 投票
2 回答
232 浏览

c++ - 模板推导/重载解析有利于 T&& 而不是 const T&

我有一对这样定义的函数模板:

如果我f如下调用:

VC++ 编译器倾向于&&重载,显然是因为它的专用性较低。我希望const&在这种情况下调用重载——该&&版本适用于f(ReturnAVector()). 有没有办法在不手动指定模板参数的情况下实现这一点?

经过相当多的努力,我想出了这个:

但是哇;这真的是获得我所追求的最简单的方法吗?

0 投票
1 回答
735 浏览

c++ - 当参数是引用时,可变参数模板构造函数选择失败

我有以下代码:

它工作正常,并打印

但是,如果第二个重载的第一个参数是一个引用,那么突然第二个重载就不会被采用,并且编译会失败:

为什么是这样?是否可以修复它并避免复制?

编辑:使用通用参考显然使它再次工作。一个const参考,这是我真正想要的,也不起作用。

此外,即使将输入参数保存为单独的值(避免右值)仍然不起作用:

0 投票
1 回答
1466 浏览

c++ - 为什么这个函数在给定右值参数的情况下返回一个左值引用?

下面定义一个min函数

有一个问题:看起来写是完全合法的

这已经用 Clang 3.5 和 g++ 4.9 进行了测试。

解决方案很简单,只需使用std::forward来恢复参数的“右值性”,即修改正文和decltypeto say

但是,我无法解释为什么第一个定义不会产生错误。


鉴于我对转发和通用引用的理解,两者都tu它们的参数类型推断为int&&传递整数文字时的类型。但是,在 的主体中min,参数具有名称,因此它们是左值。现在,条件运算符的真正复杂规则开始发挥作用,但我认为相关的行是:

  • E2 [和] E3 都是相同类型的glvalues。在这种情况下,结果具有相同的类型和值类别。

因此返回类型也operator?:应该是int&&,不是吗?但是,(据我所知)Clang 和 g++ 都min(int&&, int&&)返回了一个左值引用int&,因此允许我分配给结果。

显然,我的理解存在差距,但我不确定我到底错过了什么。任何人都可以向我解释到底发生了什么吗?


编辑:

正如 Niall 正确指出的那样,这里的问题不在于条件运算符(它int&&按预期返回类型的左值),而在于decltype. decltype说的规则

如果表达式的值类别是左值,则decltype指定T&

所以函数的返回值变成了int&& &,通过 C++11 的引用折叠规则变成了普通的int&(与我的预期相反int&&)。

但是如果我们使用std::forward,我们会将 (back) 的第二个和第三个参数operator?:转换为右值——特别是 xvalues。由于 xvalues 仍然是 glvalues(你在后面跟上吗?),同样的条件运算符规则适用,我们得到相同类型和值类别的结果:即 an int&&which 是 xvalue。

现在,当函数返回时,它会触发不同的decltype规则:

如果表达式的值类别是xvalue,则decltype指定T&&

这一次,引用折叠给了我们int&& && = int&&,更重要的是,函数返回了一个 xvalue。这使得分配给返回值是非法的,就像我们想要的那样。

0 投票
1 回答
16021 浏览

c++ - `auto && e` 在基于范围的 for 循环中有什么作用?

在使用基于范围的循环进行编程时假设我当前的规则说

尽可能使用for(auto const &e :...)for(auto &e:...)结束for(auto a: ...)

我基于我自己的经验和这个问题,例如。

但是在阅读了新的简洁 for 循环&之后,我想知道,我不应该在我的规则中用替换我的&&吗?正如这里所写,这看起来像Meyers 的 Universal References

所以,我问自己,我的新规则是否应该是

使用for(auto const &&e :...)for(auto &&e:...)尽可能...

或者这并不总是有效,因此应该是相当复杂的

检查for(auto const &&e :...)orfor(auto &&e:...)是否可能,然后考虑for(auto const &e :...)or for(auto &e:...),并且仅在需要时才不要使用引用。

0 投票
1 回答
198 浏览

c++ - 使用别名限制对单一类型的通用引用

我有一个类的成员函数,我想对其中一个参数使用完美转发。但是,被转发到的函数只接受一个 type 的参数c2Type,所以我希望调用函数也只接受c2Type参数,但显然必须保留通用引用来进行转发。似乎可以使用默认模板参数来完成,如下所示:

但是,我需要在几个成员函数上检查这种类型,而且这么长的模板似乎不友好且不可读。我想要的是为isC2Typelike创建一个别名

我认为这会使configurationMessageHandler模板看起来像

但这不会编译。在这种情况下如何正确使用别名?

0 投票
1 回答
108 浏览

c++ - 等效的 static_asserts 给出了 is_array<> 的冲突结果

在下面的代码片段中,一个静态断言通过而另一个失败:

提示:删除注释以调试类型(正确推断为int [5])。

为什么是这样?在铿锵的树干上测试。

我猜这与数组衰减为指针有关......不知何故。

解决方案:使用std::remove_reference_t, Rngwill be int (&)[5],这是对数组的引用,而不是数组。

Xeo 补充说:

将无法编译并显示r.

产生了一个错误的int**** j = r;错误(说 can't assing int[5]to int****)。

0 投票
1 回答
708 浏览

c++ - 模板化函数中 const 引用的类型推导

下面我有一个名为 ProxyCall 的模板函数,它接受一个对象、一个成员函数及其参数。它只是将调用转发给成员函数。

我希望能够在不使用模板限定符的情况下调用该函数(想象大量带有多个参数的此类调用)。当我尝试像示例中那样传递 const 引用参数时,类型推导大多有效,但编译器(msvc 和 gcc 4.9)会出错。

我的问题是:如何修改上述代码,以便编译器自动推断类型,而无需使用显式模板限定符或显式转换。考虑到编译器已经从 Widget::f 的签名中知道确切的参数类型,这似乎应该是可能的。

0 投票
1 回答
583 浏览

c++ - 具有通用引用的成员函数模板不接受左值

我一直在尝试使用模板成员函数在我的类中设置一个值。我想使用通用引用,以便我可以接受正确类型的任何变体(例如T,、、、、、、T&T&&const Tconst T&const T&&

但是,与接受通用引用的自由函数不同,我的成员函数似乎只接受右值。

0 投票
1 回答
85 浏览

c++ - VS 2013 无法根据模板参数专门化具有通用引用和返回类型的函数模板

VS 2013 说它不能在以下代码中专门化函数模板:

如果我用 替换typename T::result_typeint替换通用引用T&&T&它不会抱怨。

在我看来,上面的代码是正确的。这是编译器错误,还是我做错了什么?