我有一个SpriteHandler类,允许用户注册指向Sprite对象的指针以进行绘制,它所做的就是访问对象上的方法.我想编写一个安全捕获程序,如果用户在程序结束时忘记这样做,则会自动删除与指针关联的内存(而且对用户来说也不用担心!):
//SpriteHandler.h
class SpriteHandler {
public:
//...
void RegisterObject(Sprite* object);
bool IsRegistered(Sprite* object);
void UnregisterObject(Sprite* object);
private:
//...
static std::list<Sprite*>* _sprite = NULL;
};
//SpriteHandler.cpp
std::list<Sprite*>* SpriteHandler::_sprites = NULL;
void SpriteHandler::RegisterObject(Sprite* object) {
if(object == NULL) return;
if(_sprites == NULL) _sprites = new std::list<Sprite*>();
_sprites->push_back(object);
_sprites->sort(UDLessSprite);
}
bool SpriteHandler::IsRegistered(Sprite* object) {
return std::binary_search(_sprites->begin(), _sprites->end(), object);
}
void SpriteHandler::UnregisterObject(Sprite* object) {
if(object == NULL) return;
if(IsRegistered(object) == false) return;
_sprites->remove(object);
if(_sprites->size() <= 0) { …Run Code Online (Sandbox Code Playgroud) 我想对boost :: graph的边缘列表进行排序,如下所示:
struct Vertex{
int index;
};
struct Edge{
double weight;
};
boost::adjacency_list<boost::listS, boost::listS, boost::undirectedS, Vertex, Edge> Graph;
Run Code Online (Sandbox Code Playgroud)
添加顶点和边后,如何对边列表进行排序.首先获得最高重量的边缘?
我知道可以使用
std::sort(edgeIt_begin,edgeIt_end,compare);
Run Code Online (Sandbox Code Playgroud)
对于向量,但它不适用于std :: list.
我有一个std::list<some_object> events,我想删除该列表中除最后一个之外的所有元素.所以我想到了(正如这个帖子所建议的那样):
std::list<some_object>::iterator it = events.begin(); // Init iterator on top of list
while(it!=*std::advance(events.end(),-1)) events.erase(it++);
Run Code Online (Sandbox Code Playgroud)
不幸的是,上面的代码不起作用,因为它会产生错误:
error: invalid initialization of non-const reference of type ‘std::_List_iterator<node_info>&’ from an rvalue of type ‘std::__cxx11::list<node_info>::iterator {aka std::_List_iterator<node_info>}’
while(it!=*std::advance(event_heap.end(),-1)){
Run Code Online (Sandbox Code Playgroud)
但是,是不是list::end应该返回迭代器?我究竟做错了什么?
我将迭代器存储到列表中:
list<int> l;
l.push_back(21); l.push_back(1); l.push_back(31); l.push_back(41);
auto it = l.find(21);
Run Code Online (Sandbox Code Playgroud)
在我的算法中,每当我删除一个节点时,我都需要添加相邻的元素.像这样的东西:
auto prev = std::prev(it);
auto next = std::next(it);
*prev = *prev + *next;
l.erase(it);
Run Code Online (Sandbox Code Playgroud)
如您所见,我需要确保所有边界条件.在以下情况下,做什么std::prev()和std::next()返回什
it它本身在某些时候变得无效?我有一个不再需要的指针列表。要删除所有这些,我通常可以迭代列表:
for (T* ptr: mylist) {
delete ptr;
}
Run Code Online (Sandbox Code Playgroud)
或者我可以删除第一个或最后一个元素,直到列表为空:
while (!mylist.empty()) {
delete mylist.front(); //or mylist.back()
mylist.pop_front(); //or mylist.pop_back()
}
Run Code Online (Sandbox Code Playgroud)
对于性能和清晰度而言,首选方式是什么?
如果我有代码:
struct Test
{
int x = 10;
};
int main()
{
std::list<Test> linkedList;
std::cout << linkedList.front().x << std::endl;
}
---
out -> 0
Run Code Online (Sandbox Code Playgroud)
为什么我的 test.x 值是 0?如果我将列表更改为 int 类型,它返回 0。如果我给它一个 char 类型,我什么也得不到(或“”)。
我很好奇它是如何(以及为什么)发生在引擎盖下的。它如何处理返回任何类型的值而不退出程序或需要尝试/捕获?
在一个函数中,我使用一个std::list<Type>::const_iterator. 我无权访问容器。
有没有办法检查迭代器是否指向一个可访问的元素(即迭代器不在容器的末尾)?
注意:我使用 C++11(我不想要 C++ >= 14 的解决方案)
在我的 std::list 中,我有 10 个元素,我想将数字 1000 移到列表的后面。
https://leetcode.com/playground/gucNuPit
有没有更好的方法,使用 std::move、后插入器或任何其他 C++ 语法的 1 行有意识地实现此目的?
// Move the number 1000 to the end of the list
#include <iostream>
#include <algorithm>
#include <list>
using namespace std;
int main() {
list<int> myList({2,3,4,1000,5,6,7,8,9,10});
cout << "List before " << endl;
for(auto e : myList)
cout << e << " ";
// get iterator to the number 1000 in the list
list<int>::iterator findIter = std::find(myList.begin(), myList.end(), 1000);
int val_to_move_to_end = *findIter;
myList.erase(findIter);
myList.push_back(val_to_move_to_end);
cout << …Run Code Online (Sandbox Code Playgroud) 我有一个工作流程,其中我从可移动对象的 std::list 开始,我想遍历此列表,将满足特定条件(即一元谓词返回 true)的元素移动到不同的 std::list (例如使用back_inserter 到现有列表,甚至构建一个新列表)。
我考虑过std::list::remove_if,但如果满足条件,它只会破坏元素,并返回删除的元素总数 - 但这些元素将永远丢失。
我还考虑过std::remove_copy_if,但是如果不满足条件,则复制元素并将元素保留在原始列表中。
我的希望/假设是,基于谓词将一个列表一分为二将是一种常见的用例,以至于 std::list 将有一个成员函数来将其作为单行执行,或者可以使用 STL 算法通过迭代器来做到这一点...但我没有找到任何东西。我是否遗漏了一些明显的东西,或者这只是尚未在 STL 中实现?
我希望解决方案的伪代码类似于这个人为的“move_if”std::list 成员函数:
std::list<T> source{ /* some objects of type T */ };
std::list<T> removed{};
source.move_if(std::back_inserter(removed), [&](const auto& e){ /* test e and return a bool */ });
Run Code Online (Sandbox Code Playgroud)
或者这个为删除的元素构造并返回一个新列表:
std::list<T> removed = source.move_if([&](const auto& e){ /* test e and return a bool */ });
Run Code Online (Sandbox Code Playgroud)
如果STL中还没有固定的解决方案,那么是否有一个首选的习惯用法来“手动”执行此操作(例如在原始循环中),编译器最有可能能够相对于其他手动方法进行优化?此外,是否有技术原因导致这还不是受支持的库函数,或者我是否夸大了它对其他人的有用性?谢谢!
reinterpret_cast使用转换std::list<Derived *>为安全吗std::list<Base *>?
class Base {
...
}
class Derived : public Base{
...
}
void func(const std::list<Base *> &list);
int main() {
std::list<Derived *> list1;
// ...
func(*reinterpret_cast<std::list<Base *> *>(&list1)); // Safe ?
}
Run Code Online (Sandbox Code Playgroud)
如果是安全的转换,我们不需要复制列表,这可能会提高性能。