什么是C++ 11中的lambda表达式?我什么时候用?他们解决了哪些问题在引入之前是不可能的?
一些示例和用例将是有用的.
在C++ 14中,关联容器似乎已从C++ 11改变 - [associative.reqmts]/13说:
成员函数模板
find,count,lower_bound,upper_bound,并且equal_range不得,除非类型参与重载决议Compare::is_transparent存在.
使比较器"透明"的目的是什么?
C++ 14还提供了这样的库模板:
template <class T = void> struct less {
constexpr bool operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
template <> struct less<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) < std::forward<U>(u));
typedef *unspecified* is_transparent;
};
Run Code Online (Sandbox Code Playgroud)
因此,例如,std::set<T, std::less<T>>将不会有一个透明的比较,而是std::set<T, std::less<>> …
我想知道如何在C++中实现一个集合.如果我在不使用STL提供的容器的情况下实现自己的set容器,那么最好的方法是什么呢?
我理解STL集基于二叉搜索树的抽象数据结构.那么底层数据结构是什么?数组?
另外,如何insert()为一组工作?set如何检查元素是否已经存在?
我在维基百科上读到,实现集合的另一种方法是使用哈希表.这怎么样?
我经常发现自己想写这样的代码:
class MyClass
{
public:
void addObject(std::unique_ptr<Object>&& newObject);
void removeObject(const Object* target);
private:
std::set<std::unique_ptr<Object>> objects;
};
Run Code Online (Sandbox Code Playgroud)
但是,很多std :: set接口对std :: unique_ptrs都没用,因为查找函数需要std :: unique_ptr参数(我显然没有这些参数,因为它们由集合本身拥有).
我可以想到两个主要的解决方案.
创建临时unique_ptr以进行查找.例如,上面的removeObject()可以实现如下:
void MyClass::removeObject(const Object* target)
{
std::unique_ptr<Object> targetSmartPtr(target);
objects.erase(targetSmartPtr);
targetSmartPtr.release();
}
Run Code Online (Sandbox Code Playgroud)将原始指针映射替换为unique_ptrs.
// ...
std::map<const Object*, std::unique_ptr<Object>> objects;
};
Run Code Online (Sandbox Code Playgroud)然而,对我来说,两者似乎都有点愚蠢.在解决方案1中,erase()不是noexcept,因此临时unique_ptr可能会删除它实际上不拥有的对象,而2需要不必要地为容器存储两倍.
我知道Boost的指针容器,但与现代C++ 11标准库容器相比,它们目前的功能有限.
我最近在阅读有关C++ 14的内容,并且遇到了"将异构比较查找添加到关联容器".但是形成我对它的理解,查找类型必须与键类型相当,但原始指针不能与unique_ptrs相比.
任何人都知道更优雅的解决方案或即将添加的C++解决了这个问题?
STL中是否有分类容器?
我的意思是:我有一个std::vector<Foo>,Foo定制的类在哪里.我还有一个比较器,它将比较类的字段Foo.
现在,我在我的代码中的某个地方:
std::sort( myvec.begin(), myvec.end(), comparator );
Run Code Online (Sandbox Code Playgroud)
它将根据我在比较器中定义的规则对矢量进行排序.
现在我想在Foo该向量中插入一个class元素.如果可以的话,我想写一下:
mysortedvector.push_back( Foo() );
Run Code Online (Sandbox Code Playgroud)
会发生什么,矢量会根据比较器将这个新元素放到它的位置.
相反,现在我必须写:
myvec.push_back( Foo() );
std::sort( myvec.begin(), myvec.end(), comparator );
Run Code Online (Sandbox Code Playgroud)
这只是浪费时间,因为矢量已经排序,我需要的是适当地放置新元素.
现在,由于我的程序的性质,我不能使用,std::map<>因为我没有键/值对,只是一个简单的向量.
如果我使用stl::list,我再次需要在每次插入后调用sort.
我有一个具有唯一键的结构.我想将这些结构的实例插入到集合中.我知道要做到这一点,<运算符必须重载,以便set可以进行比较以进行插入.
以下不起作用:
#include <iostream>
#include <set>
using namespace std;
struct foo
{
int key;
};
bool operator<(const foo& lhs, const foo& rhs)
{
return lhs.key < rhs.key;
}
set<foo> bar;
int main()
{
foo *test = new foo;
test->key = 0;
bar.insert(test);
}
Run Code Online (Sandbox Code Playgroud) 我想使用lambda表达式作为std ::整数集的自定义比较.该网站上有许多解释如何执行此操作的答案,例如/sf/answers/3228982501/.事实上,
#include <vector>
#include <set>
#include <iostream>
int main() {
auto different_cmp = [](int i, int j) -> bool {
return j < i;
};
std::set<int, decltype(different_cmp)> integers(different_cmp);
integers.insert(3);
integers.insert(4);
integers.insert(1);
for (int integer : integers) {
std::cout << integer << " ";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编制和输出
4 3 1
正如所料.但是,当我尝试将此设置放在矢量中时
std::vector<std::set<int, decltype(different_cmp)>> vec_of_integers;
vec_of_integers.push_back(integers);
Run Code Online (Sandbox Code Playgroud)
编译器抱怨.我正在使用Visual Studio 2017,我根据周围的代码得到不同的编译器错误.在上面的例子中,它是
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\utility(77): error C2664: 'void std::swap(std::exception_ptr &,std::exception_ptr &) noexcept': cannot convert argument 1 from '_Ty' …Run Code Online (Sandbox Code Playgroud) 如何使用某个局部变量创建一个始终排序元素的集合?
我想要做的一个简单的例子就是这个.
int x[5] {9, 2, 3, 1, 8};
set<int, ???> my_set;
my_set.insert(0);
my_set.insert(1);
my_set.insert(4);
for (int a : my_set)
cout << a << " "; // I want the answer 1 4 0 because x[1] < x[4] < x[0]
Run Code Online (Sandbox Code Playgroud)
我想我可能能够使用a来做到这一点struct,但我不确定如何使用x改变的东西.
对于下面的代码,我不断收到此错误。
在阅读此,我相信我的错误是it++在我的for循环,我试图与更换next(it, 1),但它并没有解决我的问题。
我的问题是,迭代器是给我问题的那个吗?
#include <iostream>
#include <vector>
#include <stack>
#include <set>
using namespace std;
struct Node
{
char vertex;
set<char> adjacent;
};
class Graph
{
public:
Graph() {};
~Graph() {};
void addEdge(char a, char b)
{
Node newV;
set<char> temp;
set<Node>::iterator n;
if (inGraph(a) && !inGraph(b)) {
for (it = nodes.begin(); it != nodes.end(); it++)
{
if (it->vertex == a)
{
temp = it->adjacent;
temp.insert(b);
newV.vertex = b;
nodes.insert(newV);
n = nodes.find(newV);
temp …Run Code Online (Sandbox Code Playgroud) 我想std::set是否shared_ptr's比较指针对象,而不是指针。
我有这个例子:
std::shared_ptr<std::string> s(new std::string("abc"));
std::shared_ptr<std::string> p(new std::string("abc"));
std::set<std::shared_ptr<std::string>> S;
S.insert(s);
S.insert(p);
std::cout << S.size();
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我将相同的元素放入set但输出 2.
如何使 set 的插入使用底层字符串的比较标准?如果它不是字符串而是更复杂的对象呢?
当我意识到不可能使用一套装置而我必须创建一个新装置并拥有一个自定义排序功能来诉诸它时,我试图求助于一套.我在网上研究并试图实现我自己的自定义排序功能,但我不知道如何去做
这是我的班级
class Point2D
{
public:
int getX() const;
int getY() const;
void setX(int);
void setY(int);
bool operator < ( const Point2D& x2) const
{
if ( x != x2.x)
{
return x < x2.x;
}
if ( y != x2.y)
{
return y < x2.y;
}
};
protected:
int x;
int y;
};
Run Code Online (Sandbox Code Playgroud)
目前它是根据x值后跟y值排序,我想根据它来求助它
y值后跟x值
因此我实现了这种自定义排序
bool p2d_sortby_y(Point2D& ptd1 , Point2D& ptd2) //custom sort function
{
if ( ptd1.getY() != ptd2.getY())
{
return ptd1.getY() < …Run Code Online (Sandbox Code Playgroud)