调用swap的惯用法是:
using std::swap
swap(foo, bar);
这样,就可以为std命名空间之外的用户定义类型重载交换。
我们是否应该以相同的方式调用开始和结束?
using std::begin;
using std::end;
some_algorithm(begin(some_container), end(some_container));
或者我们应该写:
some_algorithm(std::begin(some_container), std::end(some_container));
如果some\u容器是标准容器,则不需要std::prefix
#include <iostream>
#include <vector>
#include <algorithm>
int main(){
std::vector<int>v { 1, 7, 1, 3, 6, 7 };
std::sort( begin(v), end(v) ); // here ADL search finds std::begin, std::end
}
免责声明:对于学究类型(或者学究,如果你想学究的话…),在这里,我通常将“重载”一词称为“创建名称为begin和end的函数,并且使用std::begin;使用std::end;”,相信我,这本书对我来说一点也不乏味,但读起来很难,读起来很多余<代码>:p.
我基本上会给你这种技术的可能用例,以及我的结论。
您可能需要重载std::begin
和std::end
函数的一种情况是,当您以不同的方式使用类型的开始
和end
方法时,而不是提供对对象元素的类似迭代器的访问,并且希望重载std::begin
和std::end
调用用于迭代的开始和结束方法。
struct weird_container {
void begin() { std::cout << "Start annoying user." }
void end() { std::cout << "Stop annoying user." }
iterator iter_begin() { /* return begin iterator */ }
iterator iter_end() { /* return end iterator */ }
};
auto begin(weird_container& c) {
return c.iter_begin();
}
auto end(weird_container& c) {
return c.iter_end();
}
但是,如果将range for与weird\u container
的对象一起使用,您不会也不应该做这样疯狂的事情,因为根据range for的规则,在独立函数变体之前会找到weird\u container::begin()
和weird\u container::end()
方法。
因此,这个案例提出了一个论点,即不要使用您提出的内容,因为这会破坏语言的一个非常有用的特性。
另一种情况是当您没有定义开始
和结束
方法时。这是一个更常见和适用的情况,当您想在不修改类接口的情况下扩展您的类型以使其可迭代时。
struct good_ol_type {
...
some_container& get_data();
...
};
auto begin(good_ol_type& x) {
return x.get_data().begin();
}
auto end(good_ol_type& x) {
return x.get_data().end();
}
这将使您能够在good_ol_type
(算法、范围等)上使用一些漂亮的特性,而无需实际修改其界面!这符合Herb Sutter关于通过非成员非朋友函数扩展类型功能的建议。
这是一个很好的例子,您实际上想要重载std:;开始和结束。
因为我从未见过有人做过像第一个案例那样的事情(我的例子除外),所以您真的希望使用您所建议的内容,并在适用的情况下重载std::begin
和std::end。
这里我没有包括这样一种情况,即您定义了开始和结束方法,以及开始和结束函数,这些函数的作用与方法不同。我相信这样的情况是人为的、格式错误的和/或由一个程序员造成的,他没有太多深入研究调试器或阅读新模板错误的经验。
使用这样的使用
-声明是IMO的正确方式。这也是标准对循环范围的作用:如果没有开始
或结束
成员存在,那么它将调用开始(x)
和结束(x)
,std
作为关联的命名空间(即如果ADL没有找到非成员开始
和结束
,它将找到std::begin
和std::end
)。
如果您发现使用std::begin编写;使用std::end
一直都很乏味,然后您可以使用下面的adl\U开始和adl\U结束功能:
namespace aux {
using std::begin;
using std::end;
template<class T>
auto adl_begin(T&& x) -> decltype(begin(std::forward<T>(x)));
template<class T>
auto adl_end(T&& x) -> decltype(end(std::forward<T>(x)));
template<class T>
constexpr bool is_array()
{
using type = typename std::remove_reference<T>::type;
return std::is_array<type>::value;
}
} // namespace aux
template<class T,
class = typename std::enable_if<!aux::is_array<T>()>::type>
auto adl_begin(T&& x) -> decltype(aux::adl_begin(std::forward<T>(x)))
{
using std::begin;
return begin(std::forward<T>(x));
}
template<class T,
class = typename std::enable_if<!aux::is_array<T>()>::type>
auto adl_end(T&& x) -> decltype(aux::adl_end(std::forward<T>(x)))
{
using std::end;
return end(std::forward<T>(x));
}
template<typename T, std::size_t N>
T* adl_begin(T (&x)[N])
{
return std::begin(x);
}
template<typename T, std::size_t N>
T* adl_end(T (&x)[N])
{
return std::end(x);
}
这个代码非常可怕。希望有了C 14,这可以变得不那么神秘:
template<typename T>
concept bool Not_array()
{
using type = std::remove_reference_t<T>;
return !std::is_array<type>::value;
}
decltype(auto) adl_begin(Not_array&& x)
{
using std::begin;
return begin(std::forward<Not_array>(x));
}
decltype(auto) adl_end(Not_array&& x)
{
using std::end;
return end(std::forward<Not_array>(x));
}
template<typename T, std::size_t N>
T* adl_begin(T (&x)[N])
{
return std::begin(x);
}
template<typename T, std::size_t N>
T* adl_end(T (&x)[N])
{
return std::end(x);
}
问题内容: angularjs的新手。想要将表达式写入ng-click。 例: 我想提醒游戏点击,但出现此错误: 问题答案: 当您从ng-click中请求“ alert”时,它将在$ scope上寻找该方法,但此方法不存在。 请参阅此plunkr,其中单击了指令时在示波器上使用函数调用了警报。 在控制器中,我们设置功能: 或者,您可以执行以下操作:。如果不这样做,将上下文绑定到窗口将无法正常工作。
通过将函数传递给函数call by pointer方法call by pointer将参数的地址复制到形式参数中。 在函数内部,该地址用于访问调用中使用的实际参数。 这意味着对参数所做的更改会影响传递的参数。 要通过指针传递值,参数指针将像任何其他值一样传递给函数。 因此,您需要将函数参数声明为指针类型,如以下函数swap() ,该函数swap()其参数指向的两个整数变量的值。 // functi
本文向大家介绍SQL 使用BEGIN ... END,包括了SQL 使用BEGIN ... END的使用技巧和注意事项,需要的朋友参考一下 示例
我试图使用REST API调用Microsoft Graph,但遇到了一些问题。我的应用程序最终将成为部署到Azure的web应用程序,我需要在没有登录用户的情况下通过REST调用Graph。 在调试这个程序的过程中,我试着制作出最简单的应用程序。此应用程序正在尝试使用Graph从Azure Active Directory读取用户的配置文件。 我在AAD中注册了我的应用程序,所以我有一个租户、客
属性 值发生变化后,必须立刻上报最新的值。此外,属性可以选择周期性上报,或一次性上报。 周期性上报时,每个属性的上报周期可以不同,最短周期不得低于一小时,周期要注意并发性问题,如果某一产品定在每天晚上8点准时上报属性,就有可能导致云端处理不过来而丢包,造成严重的并发性问题。 另外,因为属性在云端也需要维持一个最新属性值,所以重要的属性采用request通信方式已保证状态同步,可用在APP设备列表的
问题内容: 我在这里尝试遵循John Papa的angularJS样式指南,并已开始将我的指令切换为使用controllerAs。但是,这不起作用。我的模板似乎无法访问分配给vm的任何内容。请参见这个非常简单的plnkr示例,该示例展示了该行为。 http://plnkr.co/edit/bVl1TcxlZLZ7oPCbk8sk?p=preview 问题答案: 当使用controllerAs语法时