Menu
  • HOME
  • TAGS

Data-oriented tree traversal without recursion

Tag: c++,memory-management,tree,game-engine,data-oriented-design

I have a tree structure like this: a Model has a root Node and each Node has any number of child Nodes and also any number of Meshes.

Alot of time in my application is spent traversing this tree and doing computations like view frustrum culling and doing matrix multiplications. Currently it is naively implemented, where each Node has vectors of child Nodes and Meshes, and the tree is recursively traversed. This is very slow.

I've been looking at data-oriented design and I like the idea of it being very cache friendly. I've been thinking of something like this:

struct Mesh
{
    // misc data
    MeshID mMeshID;
}

// probably needs more information?
struct Node
{
    // begin and end index into Models 'mNodes'
    uint32_t mChildrenBegin;
    uint32_t mChildrenEnd;

    // as above but for meshes
    uint32_t mMeshesBegin;
    uint32_t mMeshesEnd;
}

struct Model
{
    std::vector<Node> mNodes;
    std::vector<Mesh> mMeshes;
}

Now I need to traverse the tree to get a list of visible meshes. At each node, I must check if the node is visible. The following branches:

  • The node is visible. All child nodes and meshes below it are visible too. Dont go deeper into this branch. Check other nodes at the same depth.
  • The node is not visible. No child nodes or meshes at this node or below it will be visible. Dont go deeper into this branch. Check other nodes at the same depth.
  • The node is partially visible. Some nodes and/or some meshes are visible. Must go deeper into hierarchy.

The tree is static. Once a model is loaded in the application, the tree never changes. So somehow surely I must be able to use this information to get an efficient structure.

I'm puzzled how to approach this though.

A couple of questions;

  1. How do I layout the nodes in memory? Is the root node the first index? Are the other nodes added based on depth?
  2. How do I iterate the tree without using recursion? I don't want to visit each node unless I really have to. For example if a node at depth=2 is not visible, all its meshes and children (and their meshes) should not be tested, but skipped completely.

Best How To :

Short version: Use 6502's pre-order answer instead. I'll leave my previous answer below because it still has some interesting code and comments.

Lay out your storage array in a semi-pre-order fashion. That is: sentinel end node, roots, first root's children, first root's first child's children, first root's first grandchild's children, and so on. Then traverse the tree using a recursive semi-pre-order traversal that keeps copies of the index information of direct ancestors and their siblings on the stack. This way, your traversal will scan the storage array from left to right with no backtracking. You don't need to visit all nodes with recursion and any skipping over subtrees that you do will only jump your scan forward in the storage array.

model.semiPreOrderTraversalRecur(model.getEnd());  // traverse the whole tree

...

// NOTE: pass prnt by *COPY* -- break Node into index portion and app. data portion; we only need the index portions here

void Model::semiPreOrderTraversalRecur(Node prnt)
{  
  Node children[prnt.mChildrenEnd - prnt.mChildrenBegin];  // just index info
  uint32_t i;

  // visit children of prnt; determine visibility etc.

  for (i = prnt.mChildrenBegin; i < prnt.mChildrenEnd; ++i)
  {
    cout << "Visiting " << mNodes[i].mVal << endl;
    mNodes[i].mInvisible = false;  // TODO: determine based on culling, etc.
    children[i - prnt.mChildrenBegin] = mNodes[i];  // just index info
  }

  // recurse on children as necessary

  for (i = 0; i < prnt.mChildrenEnd - prnt.mChildrenBegin; ++i)
    if (!children[i].mInvisible && children[i].mChildrenBegin != children[i].mChildrenEnd)
      semiPreOrderTraversalRecur(children[i]);
}

Long version (some of this is obviated): I think you can achieve what you want by adding just a bit more information to your Node structure: the index of a Node's parent and the index of the current Node. (The latter may not be strictly necessary as it can probably be derived from a pointer to the Node and the Node storage vector.)

That should give you enough contextual information to easily move "up", "down" or "sideways" to a sibling as you desire given any Node in the tree. To move "up," you simply go to the parent index. To move down, you go to any one of the child indexes. To move "sideways" to a sibling you simply increase/decrease the current Node's index (after checking that you aren't your parent's last/first child).

You might want to consider combining your Node and Mesh structures so that you can store them contiguously in one vector. Cache performance that is good for the goose is typically good for the gander. With your Mesh's stored off in another vector, they are likely far away in memory from their Node siblings and accessing them mid-traversal will put more pressure on the cache. Of course, if your Mesh's have much more data than your Node's (or vice versa), or you don't need to visit Mesh's during a traversal, then this might not be a good option as it will waste memory. Also, your Mesh's likely don't need all the tree indexes since they are terminal nodes and can be special cased when you visit a Node's children. Depending on the particulars, your original proposal for storing Mesh's separately may be superior.

In the code below, I combine your Node and Mesh structures and store them in a single vector.

#include <cstdint>
#include <iostream>
#include <vector>
#include <string>
#include <chrono>
#include <thread>

using namespace std;

struct Node
{
  uint32_t mParentIndex;    // index of parent Node in Model
  uint32_t mIndex;          // index of this Node in Model (may be possible to derive this from Node pointer and Model's vector rather than storing it)

  uint32_t mChildrenBegin;  // begin and end index of children Node in Model
  uint32_t mChildrenEnd;

  bool     mInvisible;      // used during semiPreOrderTraversal to remember no need to traverse subtree rooted at this Node

  int      mVal;            // dummy data for debugging
};

struct Model
{
  vector<Node> mNodes;  // preferably private, but your call

  Model(istream *in = NULL);

  Node *getEnd(void) { return &mNodes[0]; }  // sentinel end node that always exists and has itself as parent
  Node *getRoot(void) { return getChild(getEnd()); }

  Node *getParent(Node *curr) { return &mNodes[curr->mParentIndex]; }  // always safe to call; returns end as sentinel
  Node *getNextSibling(Node *curr) { Node *prnt = getParent(curr); return (curr->mIndex && curr->mIndex + 1 < prnt->mChildrenEnd ? &mNodes[curr->mIndex + 1] : NULL); }
  Node *getPrevSibling(Node *curr) { Node *prnt = getParent(curr); return (curr->mIndex > prnt->mChildrenBegin ? &mNodes[curr->mIndex - 1] : NULL); }
  Node *getChild(Node *curr, unsigned nth_child = 0) { unsigned index = curr->mChildrenBegin + nth_child; return (index < curr->mChildrenEnd ? &mNodes[index] : NULL); }

  void semiPreOrderTraversal(void);
  void semiPreOrderTraversalRecur(Node prnt);

private:
  int  buildFromStreamRecur(Node *curr, int val, istream &in);
};

void Model::semiPreOrderTraversal(void)
{
  Node *curr = getRoot();
  Node *next;

  cout << "Beginning Semi-Pre-Order traversal of tree!" << endl;

  if (NULL == curr)
    goto DONE;

  while (1)
  {
    // TODO: visit curr; determine and record mInvisible in curr

    cout << "Visiting " << curr->mVal << endl;
    curr->mInvisible = false;

    // try to move to sibling

    if (NULL == (next = getNextSibling(curr)))
    {
      // try to move to children of siblings

      curr = getChild(getParent(curr));  // move back to oldest sibling

      cout << "No more siblings to visit! Try to visit their children. Rewinding to oldest sibling " << curr->mVal << endl;

      while (curr->mInvisible || NULL == (next = getChild(curr)))
      {
        cout << "No children to visit of " << curr->mVal << endl;

        // shouldn't visit curr's children or it has no children
        // try to move to sibling

        if (NULL == (next = getNextSibling(curr)))  
        {
          cout << "Reached end of siblings again -> completed traversal of subtree rooted by parent " << getParent(curr)->mVal << endl;
          // ascend while we can't find a uncle to check for children to visit

          do {
            if (getEnd() == (curr = getParent(curr)))  
              goto DONE;  // got back to end -> traversal complete

            cout << "Moved back up to " << curr->mVal << endl;

          } while (NULL == (next = getNextSibling(curr)));

          cout << "Found a great^Nth uncle (" << next->mVal << ") to check for children to visit!" << endl;
        }
        // else check sibling for children to visit

        curr = next;
        cout << "Trying to visit children of " << curr->mVal << endl;
      }
      // visit children of curr

      cout << "Will visit children of " << curr->mVal << endl;
    }
    else
      cout << "Will visit sibling of " << curr->mVal << endl;

    curr = next;
  }

DONE:
  cout << "Finished Semi-Pre-Order traversal of tree!" << endl;
}

void Model::semiPreOrderTraversalRecur(Node prnt)
{  
  Node children[prnt.mChildrenEnd - prnt.mChildrenBegin];  // just index info
  uint32_t i;

  // visit children of prnt; determine visibility etc.

  for (i = prnt.mChildrenBegin; i < prnt.mChildrenEnd; ++i)
  {
    cout << "Visiting " << mNodes[i].mVal << endl;
    mNodes[i].mInvisible = false;
    children[i - prnt.mChildrenBegin] = mNodes[i];  // just index info
  }

  // recurse on children as necessary

  for (i = 0; i < prnt.mChildrenEnd - prnt.mChildrenBegin; ++i)
    if (!children[i].mInvisible && children[i].mChildrenBegin != children[i].mChildrenEnd)
      semiPreOrderTraversalRecur(children[i]);
}

Model::Model(istream *in)
{
  Node dmy, *end;

  mNodes.push_back(dmy);  // create sentinel end node

  end = getEnd();
  end->mParentIndex   = 0;
  end->mIndex         = 0;
  end->mChildrenBegin = 1;
  end->mChildrenEnd   = 1;
  end->mVal           = -1;  

  if (in)
    buildFromStreamRecur(getEnd(), 0, *in);
}

int Model::buildFromStreamRecur(Node *curr, int val, istream &in)
{
  uint32_t numChildren, i, currInd = curr->mIndex;

  // read in how many children curr will have

  in >> numChildren;

  // allocate children in mNodes and set curr's children references
  // NOTE: protect against reallocations of mNodes

  curr->mChildrenBegin = mNodes.size();

  for (i = 0; i < numChildren; ++i)
  {
    Node node;

    node.mParentIndex   = currInd;
    node.mIndex         = mNodes.size();
    node.mChildrenBegin = (uint32_t) -1;
    node.mChildrenEnd   = (uint32_t) -1;
    node.mVal           = val++;

    mNodes.push_back(node);
  }

  curr = &mNodes[currInd];
  curr->mChildrenEnd = mNodes.size();

  cout << "Node " << curr->mVal << " is complete! mParentIndex = " << curr->mParentIndex << "; mIndex = " << curr->mIndex
       << "; mChildrenBegin = " << curr->mChildrenBegin << "; mChildrenEnd = " << curr->mChildrenEnd << endl;

  // recursively build children
  // NOTE: protect against reallocations of mNodes

  for (i = 0; i < numChildren; ++i)
  {
    curr = &mNodes[currInd];
    curr = &mNodes[curr->mChildrenBegin + i];
    val = buildFromStreamRecur(curr, val, in);
  }

  return val;  
}

int main(int argc, char **argv)
{
  Model m(&cin);

  m.semiPreOrderTraversal();
  m.semiPreOrderTraversalRecur(*m.getEnd());

  return 0;
}

A non-recursive, pre-order traversal of the entire tree would look something like this:

Node *curr = model.getRoot();  // TODO: handle empty tree
Node *next;
bool  shouldnt_visit_children;

while (1)
{
  // TODO: visit curr -- determine shouldnt_visit_children

  if (shouldnt_visit_children || NULL == (next = model.getChild(curr)))
  {
    // move to next sibling; if no siblings remain then ascend while no siblings remain

    while (NULL == (next = model.getNextSibling(curr)))
      if (model.getEnd() == (curr = model.getParent(curr)))
        goto DONE;

    curr = next;
  }
  else
    curr = next;  // descend to first child
}

DONE:;

All that being said, I don't see any blazingly obvious reasons why this kind of implementation (as opposed to a linked structure like you had previously) is likely to have MUCH better cache performance. How the vectors get laid out and how you access them is what will drive your cache performance. Regardless, I don't see any compelling reasons why laying it out in any particular fashion you can't likely achieve a similar result building a linked tree similarly. For example, if you find/believe that laying out your vectors in a semi-pre-order kind of tree traversal (i.e. - the vector is laid out like: end, root, root's children, root's first child's children, root's first grandchild's children, etc.) gives optimal cache performance for your application, then it is highly likely that building a linked tree using the same semi-pre-order build order will yield similar results as your memory allocator is likely to pack your tree in memory in a similar manner as you would do explicitly. Of course, with your approach you can control this with certainty, rather than depending on your structures and associated allocators being intelligent.

Explicitly managing the layout of your Node's and Mesh's in memory may yield you some better cache performance as you can "force" it to tightly pack your objects in memory and enforce the kind of access pattern / locality you prefer -- but a decent allocator will likely achieve a similar result, particularly if the tree building is only done once at start up.

If you mostly do pre-order traversals as your questions seem to suggest, then I'd recommend laying out your storage vector in a semi-pre-order fashion, like I above described: end, root, root's children, root's first child's children, root's first grandchild's children and so on.

PS - If your traversals always start from the root, then you can eliminate the mParentIndex in Node too and instead build an explicit stack of ancestors as you walk the tree to allow you to traverse back up the tree after you descend (this is likely what the recursion did implicitly). If you need to be able to move around the tree from any random given Node, then you need to store your parent's index in the Node.

EDIT: As I mentioned in one of my comments, the semi-pre-order layout I proposed also has the property that all the descendant Mesh's of a Node can be represented in a simple numeric range [Node.mDescedantMeshBegin, Node.mDescendantMeshEnd) when you store the Mesh's separately as your proposed. So, if you need or want to build an explicit list of visible Mesh's by traversing the tree, then whenever you find a visible Node you can easily incorporate this entire range of visible descendant Mesh's into your list very easily.

EDIT2: I updated the code significantly. I added a recursive Model builder based on a semi-pre-order input stream. I fixed some bugs. Most importantly, I added a function that does a non-recursive, semi-pre-order traversal of a Model. It's not nearly as simple as a true pre-order traversal, but it may interest you. A recursive version might be much simpler -- I'll think about adding that. In my testing, the visitation of Nodes proceeds very nicely from left to right in mNodes. However, memory accesses sometimes go backwards in the storage array when we ascend back up the tree. I believe these backwards references could be removed by maintaining an explicit array of copies of ancestors (at least their index information) on the stack during a traversal. Functionality of calls like getParent() and getNextSibling() would have to be rewritten to use this array rather than jumping around in the storage vector itself, but it could be done. Then your memory accesses of mNodes will only slide from left to right, which is probably near to optimal for cache performance (assuming your tree is shallow enough that your ancestors on the stack will always be in the cache and not create undue cache pressure).

EDIT3: I added a recursive semi-pre-order traversal and it is trivial compared to the iterative version. It is also ridiculously easy to pass copies of the index portions of your Nodes to keep on the stack so that when your recursion unrolls you don't actually go back and access earlier parts of your storage array again. Instead you just look at what's on the stack, which will almost certainly be in the cache -- assuming your trees aren't super deep+wide. You do need to store copies of all the children at a given level. It's not enough to store just your direct ancestors, you also have to store their siblings. With this code and laying out your storage vector in a semi-pre-order, all your memory accesses in a traversal will scan from left to right over your storage array with no backtracking. I think you'll have near optimal cache performance. I don't see how it could get much better.

Sample input.txt: each number represents how many children the implicit current node has in pre-order fashion. In the below, the sentinel end node only has 1 child, a singular root (the code supports multiple roots if you want), the root has 5 children, the first child of the root has 0 children, the second child of the root has 2 children and so on. I used spacing to indicate the tree structure to the eye, but it's not necessary for the program itself.

1
        5
                0
                2
                        7
                                0
                                0
                                0
                                1
                                        0
                                0
                                0
                                0
                        2
                                1
                                        0
                                0
                1
                        0
                4
                        1
                                0
                        2
                                1
                                        0
                                1
                                        0
                        0
                        0
                0

Sample output:

john-schultzs-macbook-pro:~ jschultz$ clear; ./a.out < input.txt

Node -1 is complete! mParentIndex = 0; mIndex = 0; mChildrenBegin = 1; mChildrenEnd = 2
Node 0 is complete! mParentIndex = 0; mIndex = 1; mChildrenBegin = 2; mChildrenEnd = 7
Node 1 is complete! mParentIndex = 1; mIndex = 2; mChildrenBegin = 7; mChildrenEnd = 7
Node 2 is complete! mParentIndex = 1; mIndex = 3; mChildrenBegin = 7; mChildrenEnd = 9
Node 6 is complete! mParentIndex = 3; mIndex = 7; mChildrenBegin = 9; mChildrenEnd = 16
Node 8 is complete! mParentIndex = 7; mIndex = 9; mChildrenBegin = 16; mChildrenEnd = 16
Node 9 is complete! mParentIndex = 7; mIndex = 10; mChildrenBegin = 16; mChildrenEnd = 16
Node 10 is complete! mParentIndex = 7; mIndex = 11; mChildrenBegin = 16; mChildrenEnd = 16
Node 11 is complete! mParentIndex = 7; mIndex = 12; mChildrenBegin = 16; mChildrenEnd = 17
Node 15 is complete! mParentIndex = 12; mIndex = 16; mChildrenBegin = 17; mChildrenEnd = 17
Node 12 is complete! mParentIndex = 7; mIndex = 13; mChildrenBegin = 17; mChildrenEnd = 17
Node 13 is complete! mParentIndex = 7; mIndex = 14; mChildrenBegin = 17; mChildrenEnd = 17
Node 14 is complete! mParentIndex = 7; mIndex = 15; mChildrenBegin = 17; mChildrenEnd = 17
Node 7 is complete! mParentIndex = 3; mIndex = 8; mChildrenBegin = 17; mChildrenEnd = 19
Node 16 is complete! mParentIndex = 8; mIndex = 17; mChildrenBegin = 19; mChildrenEnd = 20
Node 18 is complete! mParentIndex = 17; mIndex = 19; mChildrenBegin = 20; mChildrenEnd = 20
Node 17 is complete! mParentIndex = 8; mIndex = 18; mChildrenBegin = 20; mChildrenEnd = 20
Node 3 is complete! mParentIndex = 1; mIndex = 4; mChildrenBegin = 20; mChildrenEnd = 21
Node 19 is complete! mParentIndex = 4; mIndex = 20; mChildrenBegin = 21; mChildrenEnd = 21
Node 4 is complete! mParentIndex = 1; mIndex = 5; mChildrenBegin = 21; mChildrenEnd = 25
Node 20 is complete! mParentIndex = 5; mIndex = 21; mChildrenBegin = 25; mChildrenEnd = 26
Node 24 is complete! mParentIndex = 21; mIndex = 25; mChildrenBegin = 26; mChildrenEnd = 26
Node 21 is complete! mParentIndex = 5; mIndex = 22; mChildrenBegin = 26; mChildrenEnd = 28
Node 25 is complete! mParentIndex = 22; mIndex = 26; mChildrenBegin = 28; mChildrenEnd = 29
Node 27 is complete! mParentIndex = 26; mIndex = 28; mChildrenBegin = 29; mChildrenEnd = 29
Node 26 is complete! mParentIndex = 22; mIndex = 27; mChildrenBegin = 29; mChildrenEnd = 30
Node 28 is complete! mParentIndex = 27; mIndex = 29; mChildrenBegin = 30; mChildrenEnd = 30
Node 22 is complete! mParentIndex = 5; mIndex = 23; mChildrenBegin = 30; mChildrenEnd = 30
Node 23 is complete! mParentIndex = 5; mIndex = 24; mChildrenBegin = 30; mChildrenEnd = 30
Node 5 is complete! mParentIndex = 1; mIndex = 6; mChildrenBegin = 30; mChildrenEnd = 30
Beginning Semi-Pre-Order traversal of tree!
Visiting 0
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 0
Will visit children of 0
Visiting 1
Will visit sibling of 1
Visiting 2
Will visit sibling of 2
Visiting 3
Will visit sibling of 3
Visiting 4
Will visit sibling of 4
Visiting 5
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 1
No children to visit of 1
Trying to visit children of 2
Will visit children of 2
Visiting 6
Will visit sibling of 6
Visiting 7
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 6
Will visit children of 6
Visiting 8
Will visit sibling of 8
Visiting 9
Will visit sibling of 9
Visiting 10
Will visit sibling of 10
Visiting 11
Will visit sibling of 11
Visiting 12
Will visit sibling of 12
Visiting 13
Will visit sibling of 13
Visiting 14
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 8
No children to visit of 8
Trying to visit children of 9
No children to visit of 9
Trying to visit children of 10
No children to visit of 10
Trying to visit children of 11
Will visit children of 11
Visiting 15
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 15
No children to visit of 15
Reached end of siblings again -> completed traversal of tree rooted by parent 11
Moved back up to 11
Found a great^Nth uncle (12) to check for children to visit!
Trying to visit children of 12
No children to visit of 12
Trying to visit children of 13
No children to visit of 13
Trying to visit children of 14
No children to visit of 14
Reached end of siblings again -> completed traversal of tree rooted by parent 6
Moved back up to 6
Found a great^Nth uncle (7) to check for children to visit!
Trying to visit children of 7
Will visit children of 7
Visiting 16
Will visit sibling of 16
Visiting 17
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 16
Will visit children of 16
Visiting 18
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 18
No children to visit of 18
Reached end of siblings again -> completed traversal of tree rooted by parent 16
Moved back up to 16
Found a great^Nth uncle (17) to check for children to visit!
Trying to visit children of 17
No children to visit of 17
Reached end of siblings again -> completed traversal of tree rooted by parent 7
Moved back up to 7
Moved back up to 2
Found a great^Nth uncle (3) to check for children to visit!
Trying to visit children of 3
Will visit children of 3
Visiting 19
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 19
No children to visit of 19
Reached end of siblings again -> completed traversal of tree rooted by parent 3
Moved back up to 3
Found a great^Nth uncle (4) to check for children to visit!
Trying to visit children of 4
Will visit children of 4
Visiting 20
Will visit sibling of 20
Visiting 21
Will visit sibling of 21
Visiting 22
Will visit sibling of 22
Visiting 23
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 20
Will visit children of 20
Visiting 24
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 24
No children to visit of 24
Reached end of siblings again -> completed traversal of tree rooted by parent 20
Moved back up to 20
Found a great^Nth uncle (21) to check for children to visit!
Trying to visit children of 21
Will visit children of 21
Visiting 25
Will visit sibling of 25
Visiting 26
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 25
Will visit children of 25
Visiting 27
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 27
No children to visit of 27
Reached end of siblings again -> completed traversal of tree rooted by parent 25
Moved back up to 25
Found a great^Nth uncle (26) to check for children to visit!
Trying to visit children of 26
Will visit children of 26
Visiting 28
No more siblings to visit! Try to visit their children. Rewinding to oldest sibling 28
No children to visit of 28
Reached end of siblings again -> completed traversal of tree rooted by parent 26
Moved back up to 26
Moved back up to 21
Found a great^Nth uncle (22) to check for children to visit!
Trying to visit children of 22
No children to visit of 22
Trying to visit children of 23
No children to visit of 23
Reached end of siblings again -> completed traversal of tree rooted by parent 4
Moved back up to 4
Found a great^Nth uncle (5) to check for children to visit!
Trying to visit children of 5
No children to visit of 5
Reached end of siblings again -> completed traversal of tree rooted by parent 0
Moved back up to 0
Finished Semi-Pre-Order traversal of tree!

Confused about returns in stack template

c++,templates,generic-programming

This depends on what you want the behaviour (protocol) of your class to be. Since you're logging into the error stream there, I assume you consider this an error condition to call pop() on an empty stack. The standard C++ way of signalling errors is to throw an exception. Something...

opencv window not refreshing at mouse callback

c++,opencv

your code works for me. But you used cv::waitKey(0) which means that the program waits there until you press a keyboard key. So try pressing a key after drawing, or use cv::waitKey(30) instead. If this doesnt help you, please add some std::cout in your callback function to verify it is...

OpenCV - Detection of moving object C++

c++,opencv

Plenty of solutions are possible. A geometric approach would detect that the one moving blob is too big to be a single passenger car. Still, this may indicate a car with a caravan. That leads us to another question: if you have two blobs moving close together, how do you...

Passing something as this argument discards qualifiers

c++,c++11

There are no operator[] of std::map which is const, you have to use at or find: template<> struct Record::getDispatcher<std::string> { static std::string impl(Record const& rec, std::string& const field) { return rec.fieldValues_.at(field); // throw if field is not in map. } }; or template<> struct Record::getDispatcher<std::string> { static std::string impl(Record const&...

Disadvantages of calling realloc in a loop

c,memory-management,out-of-memory,realloc

When you allocate/deallocate memory many times, it may create fragmentation in the memory and you may not get big contiguous chunk of the memory. When you do a realloc, some extra memory may be needed for a short period of time to move the data. If your algorithm does...

Checking value of deleted object

c++

It is very bad, accessing deleted objects as if they were not deleted will in the general case crash. There is no guarantee that the memory is still mapped inside the process and it could result in a virtual memory page fault. It is also likely that the memory will...

Issue when use two type-cast operators in template class

c++

What you're trying to do makes little sense. We have subclass<int>. It is convertible to int&, but also to a lot of other reference types. char&. bool&. double&. The ambiguity arises from the fact that all the various overloads for operator<< that take any non-template argument are viable overload candidates...

3 X 3 magic square recursively

c++,algorithm,math,recursion

Basically, you are finding all permutations of the array using a recursive permutation algorithm. There are 4 things you need to change: First, start your loop from pos, not 0 Second, swap elements back after recursing (backtracking) Third, only test once you have generated each complete permutation (when pos =...

Validate case pattern (isupper/islower) on user input string

c++,user-input

The simplest thing you can do is to use a for/while loop. A loop will basically repeat the same instruction for a number of n steps or until a certain condition is matched. The solution provided is pretty dummy, if you want to read the first name and last name...

undefined reference to `vtable for implementation' error

c++,build,makefile

I think you just misspelled CFLAGS in CFLAGES=-c -Wall I'm guessing this is the case since g++ ../src/main.cpp -I ../include/ does not have the -c option...

Get an ordered list of files in a folder

c++,boost,boost-filesystem

The fanciest way I've seen to perform what you want is straight from the boost filesystem tutorial. In this particular example, the author appends the filename/directory to the vector and then utilizes a std::sort to ensure the data is in alphabetical order. Your code can easily be updated to use...

Implicit use of initializer_list

c++,c++11,initializer-list

Your program is not ill-formed because <vector> is guaranteed to include <initializer_list> (the same is true for all standard library containers) §23.3.1 [sequences.general] Header <vector> synopsis #include <initializer_list> ... Searching the standard for #include <initializer_list> reveals the header is included along with the following headers <utility> <string> <array> <deque> <forward_list>...

MFC visual c++ LNK2019 link error

c++,mfc

The header file provides enough information to let you declare variables. And for that matter to just compile (but not link) code. When you link, the linker has to resolve e.g. function references such as a reference to ServerConnection::getLicenceRefused, by bringing in the relevant machine code. You have to tell...

Passing iterator's element to a function: wrong type of pointer

c++,pointers,stl,iterator

Preferred option: change isPrime to take a long (and pass *it to it). Secondary option: pass &*it instead of it. Your original code doesn't work because it is an iterator (which is a class) whereas the function expected long int * and there is no implicit conversion from iterator to...

Explicit instantiation of class template not instantiating constructor

c++,templates,constructor,explicit-instantiation

When the constructor is a template member function, they are not instantiated unless explicitly used. You would see the code for the constructor if you make it a non-template member function. template<typename T> class test { public: /*** template<typename T> test(T param) { parameter = param; }; ***/ test(T param)...

std::condition_variable – notify once but wait thread wakened twice

c++,multithreading

Converting comments into answer: condition_variable::wait(lock, pred) is equivalent to while(!pred()) wait(lock);. If pred() returns true then no wait actually takes place and the call returns immediately. Your first wake is from the notify_one() call; the second "wake" is because the second wait() call happens to execute after the Stop() call,...

c++ extend constructor of same class (no inheritance)

c++,constructor

Yes you can as of C++11 standard. Wiki article. Also a quick empirical verification: using namespace std; class A { public: A() { cout << "Hello "; } A(int x) : A() { cout << "World!" << endl; } }; int main() { A a(1); return 0; } Prints: Hello...

How can I access the members of a subclass from a superclass with a different constructor?

c++,inheritance,constructor,subclass,superclass

This map: typedef map<string, Object> obj_map; only stores Object objects. When you try to put an Image in, it is sliced down and you lose everything in the Image that was not actually part of Object. The behaviour that you seem to be looking for is called polymorphism. To activate...

Marshal struct in struct from c# to c++

c#,c++,marshalling

Change this: [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 36)] private string iu; to this: [MarshalAs(UnmanagedType.LPStr)] private string iu; Note that this code is good only to pass a string in the C#->C++ direction. For the opposite direction (C++->C#) it is more complex, because C# can't easily deallocate C++ allocated memory. Other important thing:...

Test if string represents “yyyy-mm-dd”

c++,command-line-arguments

If you can use boost library you could simple do it like this: string date("2015-11-12"); string format("%Y-%m-%d"); date parsedDate = parser.parse_date(date, format, svp); You can read more about this here. If you want a pure C++ solution you can try using struct tm tm; std::string s("2015-11-123"); if (strptime(s.c_str(), "%Y-%m-%d", &tm))...

template template class specialization

c++,templates,template-specialization

The specialization still needs to be a template template argument. You passed in a full type. You want: template <class Type, class Engine> class random_gen<std::uniform_real_distribution, Type, Engine> { ... }; Just std::uniform_real_distribution, not std::uniform_distribution<Type>. ...

How can I convert an int to a string in C++11 without using to_string or stoi?

c++,string,c++11,gcc

Its not the fastest method but you can do this: #include <string> #include <sstream> #include <iostream> template<typename ValueType> std::string stringulate(ValueType v) { std::ostringstream oss; oss << v; return oss.str(); } int main() { std::cout << ("string value: " + stringulate(5.98)) << '\n'; } ...

Storing columns on disk and reading rows

c++,file,matrix,io

Mentioned solution with fseek is good. However, it can be very slow for large matrices (as disks don't like random access, especially very far away). To speed up things, you should use blocking. I'll show a basic concept, and can explain it further if you need. First, you split your...

C++11 Allocation Requirement on Strings

c++,string,c++11,memory,standards

Section 21.4.1.5 of the 2011 standard states: The char-like objects in a basic_string object shall be stored contiguously. That is, for any basic_string object s, the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0 <= n < s.size(). The two...

create vector of objects on the stack ? (c++)

c++,vector,heap-memory

Yes, those objects still exist and you must delete them. Alternatively you could use std::vector<std::unique_ptr<myObject>> instead, so that your objects are deleted automatically. Or you could just not use dynamic allocation as it is more expensive and error-prone. Also note that you are misusing reserve. You either want to use...

Type function that returns a tuple of chosen types

c++,templates,c++11,metaprogramming

You can do this without recursion by simply expanding the parameter pack directly into a std::tuple: template<My_enum... Enums> struct Tuple { using type = std::tuple<typename Bind_type<Enums>::type...>; }; To answer your question more directly, you can declare a variadic primary template, then write two specializations: for when there are at least...

Method returning std::vector>

c++

Your error is actually coming from: array.push_back(day); This tries to put a copy of day in the vector, which is not permitted since it is unique. Instead you could write array.push_back( std::move(day) ); however the following would be better, replacing auto day...: array.emplace_back(); ...

No match for 'operator*' error

c++,c++11

As @101010 hints at: pay is a string, while hours_day is a float, and while some languages allow you to multiply strings with integers, c++11 (or any other flavor of c) doesn't, much less allow strings and floats to be multiplied together.

Make a triangle shape in C++

c++

This code works fine for a right angled triangle - * ** *** But I guess you want a triangle like this - * *** ***** Try this - #include <iostream> using namespace std; int main() { int i, j, k, n; cout << "Please enter number of rows you...

Same function with and without template

c++,c++11

The main reason to do something like this is to specialize void integerA(int x) to do something else. That is, if the programmer provides as input argument an int to member function abc::integerA then because of the C++ rules instead of instantiating the template member function the compiler would pick...

Parameters to use in a referenced function c++

c++,pointers,reference

Your code makes no sense, why are you passing someStruct twice? For the reference part, you should have something like: void names(someStruct &s) { // <<<< Pass struct once as a reference cout << "First Name: " << "\n"; cin >> s.firstname; cout << "Last Name: " << "\n"; cin...

Translating a character array into a integer string in C++

c++,arrays,string

If you want a sequence of int, then use a vector<int>. Using the key_char string, the values of the chars in it will serve as the initial value of the ints. std::vector<int> key_num(key_char.begin(), key_char.end()); Then, iterate over each character of key_num and convert it to the equivalent int value for...

C++ Isn't this a useless inline declaration?

c++,inline,private,member,protected

The Compiler can Access everything. The restrictions are only valid for the programmer. This means there are no restrictions for the Compiler to Access any variables! At the end every variable is just translated to an address which can be accessed. So for the Compiler it is no Problem to...

C++ & Qt: Random string from an array area

c++,arrays,string,qt,random

You should use the random header. #include <random> std::default_random_engine generator; std::uniform_int_distribution dist(0, 5); int StringIndex = dist(generator); std::string ChosenString = characters[StringIndex]; The above will generate a random index into your array. If you want to limit the range, change the constructor of dist, for example (dist(0,2) would only allow for...

C++ template template

c++,templates

Your issue is that std::deque (and other standard containers) doesn't just take a single template argument. As well as the stored type, you can specify an allocator functor type to use. If you don't care about these additional arguments, you can just take a variadic template template and be on...

how to sort this vector including pairs

c++,vector

You forgot the return statement in the function bool func(const pair<int,pair<int,int> >&i , const pair<int,pair<int,int> >&j ) { i.second.first < j.second.first ; } Write instead bool func(const pair<int,pair<int,int> >&i , const pair<int,pair<int,int> >&j ) { return i.second.first < j.second.first ; } Also you should include header <utility> where class std::pair...

segfault accessing qlist element through an iterator

c++,iterator,qlist

(Edited away first "answer", this is an actual attempt at an answer) My guess: QList<Msg> messages() const { return _messages; } It's returning a copy of the QList _messages, rather than a reference to it. I'm not sure that it would give the results you're seeing, but it looks wrong...

dispatch response packet according to packet sequence id

c++,boost,boost-asio

You could use std::promise and std::future (or their boost counterparts if your are not yet on C++11). The idea is to store a std::shared_ptr<std::promise<bool>> with the current sequence id as a key in the map whenever a request is sent. In the blocking send function you wait for the corresponding...

Can python script know the return value of C++ main function in the Android enviroment

python,c++

For your android problem you can use fb-adb which "propagates program exit status instead of always exiting with status 0" (preferred), or use this workaround (hackish... not recommended for production use): def run_exe_return_code(run_cmd): process=subprocess.Popen(run_cmd + '; echo $?',stdout=subprocess.PIPE,shell=True) (output,err)=process.communicate() exit_code = process.wait() print output print err print exit_code return exit_code...

pointer to pointer dynamic array in C++

c++,arrays,pointers

The valid range of indices of an array with N elements is [0, N-1]. Thus instead of for example this loop for (int i=1; i <= n; i++) ^^^^ ^^^^^^ you have to write for ( int i = 0; i < n; i++ ) As you used operator new...

.cpp:23: error: cannot convert ‘std::string’ to ‘const char*’ for argument ‘1’ to ‘int atoi(const char*)’

c++,string

Use stoi, it's the modern C++ version of C's atoi. Update: Since the original answer text above the question was amended with the following error message: ‘stoi’ was not declared in this scope Assuming this error was produced by g++ (which uses that wording), this can have two different causes:...

Algorithm for [inclusive/exclusive]_scan in parallel proposal N3554

c++,algorithm,parallel-processing,c++14

Parallel prefix sum is a classical distributed programming algorithm, which elegantly uses a reduction followed by a distribution (as illustrated in the article). The key observation is that you can compute parts of the partial sums before you know the leading terms.

Add more features to stack container

c++,visual-c++,stl

If this is interview question or something , and you have to do it anyways , you can do this like ,below code . derive from std::stack , and overload [] operator #include <iostream> #include <algorithm> #include <stack> #include <exception> #include <stdexcept> template <typename T> class myStack:public std::stack<T> { public:...

ctypes error AttributeError symbol not found, OS X 10.7.5

python,c++,ctypes

Your first problem is C++ name mangling. If you run nm on your .so file you will get something like this: nm test.so 0000000000000f40 T __Z3funv U _printf U dyld_stub_binder If you mark it as C style when compiled with C++: #ifdef __cplusplus extern "C" char fun() #else char fun(void)...

How can I tell clang-format to follow this convention?

c++,clang-format

Removing BreakBeforeBraces: Allman Seems to do what you want (for me). I'm using SVN clang though. Although you probably wanted it there for a reason. According to the clang-format docs, the AllowShortBlocksOnASingleLine should do exactly what you want (regardless of brace style). This might be a bug in clang-format....

Copy text and placeholders, variables to the clipboard

c++,qt,clipboard

You're not using the function setText correctly. The canonical prototype is text(QString & subtype, Mode mode = Clipboard) const from the documentation. What you want to do is assemble your QString ahead of time and then use that to populate the clipboard. QString message = QString("Just a test text. And...

Incorrect Polar - Cartesian Coordinate Conversions. What does -0 Mean?

c++,polar-coordinates,cartesian-coordinates

You are converting to cartesian the points which are in cartesian already. What you want is: std::cout << "Cartesian Coordinates:" << std::endl; std::cout << to_cartesian(to_polar(a)) << std::endl; std::cout << to_cartesian(to_polar(b)) << std::endl; //... Edit: using atan2 solves the NaN problem, (0, 0) is converted to (0, 0) which is fine....

Strings vs binary for storing variables inside the file format

c++,file,hdf5,dataformat

Speaking as someone who's had to do exactly what you're talking about a number of time, rr got it basically right, but I would change the emphasis a little. For file versioning, text is basically the winner. Since you're using an hdf5 library, I assume both serializing and parsing are...

Undefined behaviour or may be something with memset

c++,undefined-behavior

The A[32] in the method is actually just a pointer to A. Therefore, sizeof is the size of *int. Take the following test code: void szof(int A[32]) { std::cout << "From method: " << sizeof(A) << "\n"; } int main(int argc, char *argv[]) { int B[32]; std::cout << "From main:...

Why are shaders and programs stored as integers in OpenGL?

c++,opengl,opengl-es,integer,shader

These integers are handles.This is a common idiom used by many APIs, used to hide resource access through an opaque level of indirection. OpenGL is effectively preventing you from accessing what lies behind the handle without using the API calls. From Wikipedia: In computer programming, a handle is an abstract...