mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Wow! You are stepping into a problem that is bigger than you can comprehend (no offense). This problem is the general problem of collision detection. To do this correctly and efficiently is a huge deal.

Generally, to solve this problem, you need to solve a number of very difficult problems.

First, you need a means to efficiently determine if two geometries are intersecting (i.e. colliding). There are a number of ways to do this ranging from closed-form minimum-distance formulas between primitive geometric volumes (boxes, cylinders, spheres, etc.), to optimization-based mathematical programming to determine the minimum distance or interception between meshes (set of polygons attached together making up the boundary of a 3D object, i.e. boundary representations (often called "B-Rep" for short)). The latter usually involves efficient mathematical programming algorithms from simple linear programs (e.g. Dual Simplex Method) to quadratic programs (e.g. Ellipsoid Method) to non-linear methods (e.g. general non-linear optimization methods, like LBFGS). In all cases, the methods generally operate only on convex geometries.

Second, if you deal with non-convex geometries, you need to decompose the volumes into a composite of convex geometries (i.e. Convex Decomposition). And that isn't a particularly easy task by itself. Beyond the complexity of just testing sub-meshes for being convex or not, and actually finding a split that works, there are measures involved to figure out the best split for the mesh such that …

Ezzaral commented: Nice post! +15
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Read this wiki.

Basically, any pointers in a program is "logical" (or virtual), never physical (unless you are not running under an operating system). Managing the memory allocated for processes is a job for the OS (i.e. the OS manages where memory is allocated to store the executable code for the running processes, the memory used by processes (stack and heap), the same for kernel processes). The OS needs the freedom to decide what should be in RAM (because it is needed a lot), what is paged to files, how to arrange memory blocks, etc. etc. To do all this in a way that goes completely unnoticed by processes (the values of the pointers don't change), it has to create a layer of memory mappings that map the pointers that a process has to their actual physical location. Realizing that mapping is a very complex system (with process-sharing, caching and synchronization issues). But, certainly, the pointers that a program holds are indeed virtual addresses, the proof is simple: they don't change even as the process memory is relocated. Another indication of that is also the fact that if you access memory that isn't allocated to the current process, you get a "segmentation fault" or "access violation" error from the OS, this occurs while the address mapping is done and if the virtual address is not in the process' virtual address space.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>edit: it is <thread> the library u are talking about? if yes, it seems my compiler does not support it
i am using MSVC 2010 express

Yes, that is the library I am talking about. Use Boost.Thread if your compiler does not support this library yet.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Since C doesn't have templates, why would you want to check if a type is unsigned or not? You will always know the exact type of anything, so knowing if a type is unsigned or not is simply a matter of checking the documentation on the type in question. Also, because C doesn't have overloaded functions, it would be pretty hard to achieve this anyways.

The Boost is_unsigned template (compatible with C++03) is essentially implemented as a number of specialization of the template for each fundamental type with the value of true for those which are unsinged and false otherwise, and if you have a custom type that is unsigned, you just provide an additional specialization for your custom type.

In other words, there is no reliable way, via casts, to determine if a type is unsigned. Most integral casts involve a policy of "not changing the bits", so casting back and forth a value is not really going to work.

Besides using templates or compiler intrinsics (which is what std::is_unsigned uses), you could maybe succeed with this method:

template<class T>
inline 
bool IsValidUnsignedLong(T)
{
    return T(-1) > T(0);
}

//or as a template:
template <typename T>
struct is_unsigned {
  static const bool value = (T(-1) > T(0));
};

But I doubt that the above will always work. But if it does, it would work in C (assuming you don't know what type it is).

EDIT: I just looked up the C++ standard and it …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The streams work on a streambuf object. The streambuf is an abstract base class that provides a buffer interface for use by the stream objects (like ostream and istream). Two derived class are provided by the standard, the filebuf and stringbuf classes (where, obviously, the filebuf reads/writes to a file and the stringbuf reads/writes to a string (or character array)).

To associate a stream with a given streambuf object, you can use the rdbuf() function.

If you want to actually create your own streambuf derived class, then I don't really know how to do that, it is probably pretty hard. But usually, either the filebuf or stringbuf should be sufficient for a given application, for instance, most OSes implement things like COM-ports, internet sockets, or console/terminal IO as files (things like look like files anyways, pseudo-files if you want).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Why not go for the standard threads? They have just been added to C++ (with C++11), so you might as well learn to use that. The standard thread libraries are supported (at least most of it) by most compilers. It is also almost exactly the same as the Boost.Thread library (with a few minor changes). So, if the standard thread library is not yet supported by your compiler, start getting used to the Boost.Thread library and making the switch later will be really easy.

There is no reason to learn to use the Windows threading functions (or the POSIX threading functions for that matter). These functions are C-style functions that are just a pain in the *** to work with. It is only worth knowing if you are doing more advanced kinds of multi-threading programming in which case you might want to exploit certain advanced synchronization features, in either WinAPI or pthreads, that may not be available in the standard threading library. The main OS APIs, Win32 API and POSIX (for Windows and *nix systems, respectively) differ quite fundamentally in the entrails of the OS on how they implement multi-threading (scheduling threads, kernel vs. user-side calls, interrupts, etc.) and that leads to certain synchronization, message-passing, and inter-thread communication features that are unique to either API, only if you want to exploit those additional features should you really consider learning about them.

For middle-of-the-road multi-threading, the standard or Boost thread library are very good, and inherently more portable, of …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You do a cast to unsigned int and then you cast it back to T . This kind of cast generally has undefined behavior, but it is defined that doing (T)(U)t for T t; should yield the same value as t . So, your code is merely checking a standard-defined behavior, if it didn't yield true, it means your compiler is broken.

Your implementation and your strategy for checking if a value is unsigned is not possible, it has too much undefined or implementation-defined behavior, and according to the standard, it shouldn't work in any case. You dangerously run into the possibility of overflow as well.

If you need a meta-function to determine if a type is unsigned or not, you should use the std::is_unsigned template. As in:

#include <type_traits>

template<class T>
inline 
constexpr bool IsValidUnsignedLong(T)
{
    return std::is_unsigned<T>::value;
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The error message means that your int energySystem::getEnergyLevel() should be made a const member function in order to be called with a const energySystem object. That is, you need the following prototype:

int energySystem::getEnergyLevel() const; //notice 'const' here.
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

> why it is not in the std::tuple or boost::tuples::tuple class since other operators are already defined (comparison).

IIRC, there was a suggestion to overload the + operator for std::tuple<>. Not for element by element arithmetic plus, but for concatenation of tuples a la std::string.

There would be a similar ambiguity in the case of operator- (element by element minus or symmetric difference?), operator* ( element by element multiply, vector cross product or scalar dot product?).

IMHO, it was best that none of these operators were overloaded by the standard.

That makes sense. I understand the ambiguity.

I ended up implementing my own. If anyone is interested or find his way to this thread looking for an arithmetic-tuple class template, I have attached it to this post. My implementation is compatible with both C++11 and C++03 (using Boost Tuples), and I provide it, as is, with no guarantee, of course. Any review or comments on it is welcomed, of course.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>an ampersand right before the function name

That's the wrong way to think about it. The ampersand is right after the return-type declaration, in other words, the ampersand is part of the definition of the return-type. In this case, the function returns a reference to an int variable. It also takes its two parameters by reference.

Read this for a deeper explanation of references.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Thanks for the reply vijayan, but my question is about tuples of heterogeneous types, not vector-like classes like vararray or TinyVector or many others of the kind.

Here is a more specific example of my problem. Say, I have a bunch of "state-space system" types each with some typedef for the type that represents the state-vector (doesn't have to be a vector), but they are all arithmetic (have + - -= += operators and a few more, like scalar multiplication). Say I have this code (very simplified):

template <typename SystemType>
struct system_traits {
  //..
  typedef typename SystemType::state_diff_type state_diff_type;
  //..
};


//Now, I want to combine many systems together, and for that I need to make composite state descriptors that are also arithmetic:
template <typename... Systems>
struct composite_system {
  //..
  typedef std::tuple< typename system_traits<Systems>::state_diff_type... > state_diff_type;
  //..
};

//Now, I have a concept-check class:
template <typename System>
struct StateSpaceSystemConcept {
  //..
  typename system_traits< System >::state_diff_type dx;

  BOOST_CONCEPT_USAGE(StateSpaceSystemConcept)
  {
    //..
    dx = dx + dx; 
    dx += dx;
    dx -= dx; 
    //.. etc..
  };
};

int main() {
  BOOST_CONCEPT_ASSERT((StateSpaceSystemConcept< composite_system< SystemA, SystemB, SystemA> >));
  //   ERROR: no operator+ for type std::tuple<..> 
  //    .. and so on for other operators.
};

As I said, I can pretty easily write a wrapper for the tuple type to add all those operators, but I was wondering if that didn't exist already and for that matter, why it is not in the std::tuple or boost::tuples::tuple class since other operators are already defined (comparison).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>i have never considered optimizating

It shouldn't be your concern either. You shouldn't have to worry about optimizing your code until you have strong evidence that your performance is below what you need.

>>i don't have much experience

Gain more experience, worry about other things, like good software design, coding practices, expanding your knowledge of C++ syntax, etc.

>>i might consider changing it tho. is GCC free?

Well, this is no reason to switch compilers or IDE, but it is certainly good to learn to work with different compilers.

Yes, GCC is free. Under windows, you can use MinGW or Cygwin, for other OSes you can use GCC directly. Some IDEs can also be downloaded with MinGW included, like CodeBlocks.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Hey,

I have a set of types which are all arithmetic (have operators for addition, subtraction, multiplication, etc.). I want to aggregate any number of them into a single object, so I'm using the std::tuple class template and the <tuple> library (and Boost.Tuple for backward compatibility).

My question is a bit of a shot in the dark: Has anyone heard or seen a tuple-like class template that implements all the arithmetic operators?

For example, the std::tuple and boost::tuple classes both implement all the comparison operators which will only compile correctly if all the types contained in the tuple also have the comparison operators in question. I am wondering why there aren't the same provisions for the arithmetic operators?

I could easily implement this myself (but it can amount to a bit of trouble especially for backward compatibility with C++03), but I'm just wondering if anyone heard of one "arithmetic tuple" template that exists already.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>it seems to me like the index method is both cleaner and faster

I think your time measuring method is not good and your optimizations are not turned on, because your performance results are not correct.

I tried this code:

#include <iostream>
#include <vector>

#include "boost/date_time/posix_time/posix_time.hpp"

int main(int argc, char** argv) {
  
  boost::posix_time::ptime t = boost::posix_time::microsec_clock::local_time();
  std::vector<int> vect(100000000,0);
  boost::posix_time::time_duration dt = boost::posix_time::microsec_clock::local_time() - t;
  std::cout << "Initializing an empty vector of 100,000,000 ints in: " << dt.total_milliseconds() << " milliseconds" << std::endl;

  t = boost::posix_time::microsec_clock::local_time();
  for(int i = 0; i != vect.size(); ++i)
    vect[i] = 1;
  dt = boost::posix_time::microsec_clock::local_time() - t;
  std::cout << "Looping a vector 100,000,000 with vect[i] in: " << dt.total_milliseconds() << " milliseconds" << std::endl;

  t = boost::posix_time::microsec_clock::local_time();
  for(auto it = vect.begin(); it != vect.end(); ++it)
    *it = 1;
  dt = boost::posix_time::microsec_clock::local_time() - t;
  std::cout << "Looping a vector 100,000,000 with *it in: " << dt.total_milliseconds() << " milliseconds" << std::endl;

  t = boost::posix_time::microsec_clock::local_time();
  for(int& x : vect)
    x = 1;
  dt = boost::posix_time::microsec_clock::local_time() - t;
  std::cout << "Looping a vector 100,000,000 with range-based for-loop in: " << dt.total_milliseconds() << " milliseconds" << std::endl;

  t = boost::posix_time::microsec_clock::local_time();
  std::for_each(vect.begin(), vect.end(), [](int& x) { x = 1; });
  dt = boost::posix_time::microsec_clock::local_time() - t;
  std::cout << "Looping a vector 100,000,000 with for-each loop in: " << dt.total_milliseconds() << " milliseconds" << std::endl;

  return 0;
};

And compiled with the following:

$ g++ for_loop_perf.cpp -std=c++0x -O3 -lboost_date_time -o for_loop_perf

And the output is, as expected:

Initializing …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Lines 54 to 61 are off by one. You should know that indices in C/C++ go from 0 to N-1, that is, for an array hotspot* hotspots[8]; , the indices should go from 0 to 7, not from 1 to 8. This is really basic stuff.

Your default constructor does not initialize the "hotspots" array. And, as rubberman said, this means that the Test->checkHotspot(1) call returns a NULL pointer. When it is dereferenced in the mousewithin() function, you get a crash (segmentation fault or Access Violation, depending on your OS).

Your "screen" class holds dynamically allocated memory, yet you don't have a destructor (and nor do you have a deep-copy constructor and assignment operator). That's an error, you have memory leaking, and possibly more problems down the line. Read my tutorial on RAII for details.

You may have other errors, but start by solving the above-mentioned issues.

tajendra commented: rightly directed +2
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>As a side note, how does the range-based for-loop do for efficiency? I'm guessing that it's going to be as good as it can be?

I believe the range-based for-loop is just syntactic sugar for the iterator version of the for-loop. By that I mean that these two loops are probably exactly the same:

for(int& x : myvec)
{
    // access by 'x'
}

// The above is most probably exactly the same as this:
for(auto it = myvec.begin(); it != myvec.end(); ++it)
{
    int& x = *it;

    // access by 'x'
}

//which is also exactly the same as:
for(auto it = myvec.begin(); it != myvec.end(); ++it)
{
    // access by '*it'
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Inlining functions is, first of all, something that the compiler does. So, the first rule is that the compiler has to be able to find the definition of the function (definition = function body). As Fbody said, the compiler only looks at one "translation unit" at a time (a translation unit (TU) is the technical term for what Fbody (wrongly) calls a "compilation unit"). Basically, a TU is what turns into one object file (.o or .obj), it usually comes from the compilation of a single .cpp file (along with all the header-file code/declarations that it includes).

So, if you have the function bodies in a separate cpp file, and compile them separately, the compiler, when compiling the main TU, will not see the definitions of the functions that are in another TU, and thus, will not be able to inline anything.

Now, if you declare a function prototype with the "inline" keyword, it has two effects. First, it _suggests_ to the compiler that this function should be inlined during the compilation. Second, it marks the function for "internal linkage", meaning that the compiler should look for the function definition within the current translation unit in order to perform the linkage (linkage, here, means to replace every call to that function by either a jump to the address of the function or by an inline expansion of the function's body at the call-site). If the compiler does not find the function definition within the current TU, it will …

NP-complete commented: good info...:) +5
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

It is also more efficient (don't use random-access, via an index, if it is not needed). It is also more idiomatic.

Also, the new C++ standard makes it a bit cleaner with the "auto" keyword, as so:

vector<int> myvec; // let's assume it's initialized
for(auto it = myvec.begin( ); it != myvec.end( ); ++it)
{
    // code
    // access by '*it'
}

Also, note that C++11 introduces yet a third and nicer way to do this for-loop, using the range-based syntax:

vector<int> myvec; // let's assume it's initialized
for(int& x : myvec)
{
    // code
    // access by 'x'
}

@ravenous: If the vector is not declared as "volatile", the evaluation of "size" is probably not done more than once. And since STL containers are templates (and thus have function definitions available to the compiler), functions like "begin()" "end()" or "size()" are most probably inlined (so you don't even get the cost of a function call). It is also possible that a clever compiler will be able to optimize the first version (with index) such that it boils down to exactly the same as the second version (with iterators), but, in theory, the iterator version has the best chance of being more efficient.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Basically, optimization flags play a big role in increasing the performance of an application.

You need to first make sure you compile under "Release" mode, which will disable debugging hooks and features (so you won't be able to stop the program with break-points and step through it). Those debugging hooks are not necessary once you have finished debugging the application.

Then, you can enable a number of optimizations. Basically, you can choose between fast code ( /O2 ) or small code ( /O1 ). And you can also enable global optimizations ( /GL ). In general, the fastest code is generated with the /Ox compilation flag. I'm not familiar enough with Visual C++ build option menus to direct you to where you can change those settings, but you get the general idea: go through the build options and enable anything that says "optimization". At worst, you can add /Ox to the custom compilation flags (somewhere in the menus). Here is a complete list of compilation flags for MSVC. Here is an overview of high-end optimizations in MSVC. Basically, if you have knowledge of your architecture's hardware accelerations, you can specify that in order to make use of them to increase performance.

After disabling debugging and enabling all optimizations, your program should function exactly the same as before, just a lot faster (4-5 times faster). If it doesn't work correctly anymore, then you have bugs in your program.

Cainer commented: Perfect answer. Thank you very much. +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>Is it impossible to find the base address using two of these info??

"Insanity: doing the same thing over and over again and expecting different results." -Albert Einstein

How many times will you ask the same question and expect a different answer?

The answer is clear, to find the base address of the struct, you need to know which member that pointer points to, if you don't know which member it is, only its address, then it is IMPOSSIBLE to find the base address of the struct.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>The problem is quite clear....I need to find the base address of the struct .I know that the name is Check and the address of one of the member is p

And the answer is clear: IT IS IMPOSSIBLE!

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Assuming you are using GCC (which usually comes with CodeBlocks), then you need to read these instructions.

You can also create assembly listings files (with .s extension) which contain a full compilable assembly code (in a human readable listing). Then, you can assemble the assembly listings file into an object file (with .o extension) and then link it to the rest of your application.

Actually creating fully functioning functions in assembly is not a simple task, even for the simplest function. The easiest, if you are looking to optimize, is to write your function in C, and then compile as $ gcc -S my_source.c -o my_source.s to generate the assembly listing for your source file, and then manually optimize the assembly code before completing the compilation into the object file.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Uhmm... saving a function to a file to be able to call it later from anywhere else... if I'm not mistaken (rethorical), this is called a Dynamic Link Library (DLL) (in Windows) or a Shared Object (SO) (in *nix).

Any way you want to do what you want to do, it will either have to be based on or going through the use of a shared library (.dll or .so) file. So, I suggest you look into that topic.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>you should never use code you can't see's implimentation because It might not be what you need.

That's idiotic, as Narue said. The interface, the behaviour and the performance of each operation on std::map or std::set are very strictly specified, and their performance specifications (time-complexity of insertion (logN) and look-ups (logN)) implies that a balanced BST must be used in the implementation. When you have good specification of the interface, behaviour and performance, there is no need to be aware of its implementation details to be able to use it and have a clear idea of the resulting behaviour.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>I had difficulty using the vector-of-boolean interface.

Exactly, that's the main argument that people make against the vector-of-bool specialization. Let me give a bit more background on this problem. The original decision to include a specialization was from the memory optimization point-of-view. But people soon realized that, even though the vector-of-bool provides an interface which essentially looks like the general vector template, it makes some hidden assumptions (like the proxy-object for lvalue indexing) that essentially break the interface. It was a simple mistake, nobody's perfect, including the architects of the STL. For example, in the case of indexing, they were satisfied by the fact that the proxy-object could act as a bool& variable in a statement like vect_bool[i] = true; , but the problem is that you cannot bind a bool& variable to this lvalue obtained from the indexing (including sending it to a function that takes a bool& parameter), i.e., you cannot do bool& b_ref = vect_bool[i]; .

The gist of the debate is this:

On one side, the more purist side, people argue that, by definition, the reference that is returned by the non-const indexing of any STL container is not required to be T& , it is only required to be of the type std::vector<T>::reference which may or may not be T& . Just like random-access iterator is not required to be T* (but it could), the only requirement is that it acts in a way that is similar to a T* . Technically …

NathanOliver commented: Great explanation +9
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>In my opinion, I think this was a bad idea implementing a specialized version for vector of bools.

Well, the specialization of vector for the bool type is and continues to be a very controversial issue, with renowned experts on either sides. Personally, I haven't looked into it enough to form my own opinion. But I do appreciate the fact that the new standard is more explicit about noting that the general vector class template is not the same as the vector<bool> class and that they should be regarded as two distinct containers.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>how do I tell what kind of Linux I have?

You run (from a terminal, any folder):

$ cat /etc/lsb-release
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>Is it possible to have multi-dimensional vectors like it is with arrays?

Yes. The way std::vector works (and all other STL containers) is that you provide, between < > , the type of elements you want to contain in the vector. Now, in my example, std::vector<int> will contain "int" values. If you want a multi-dimensional vector, just make a vector of vectors, as in std::vector< std::vector<int> > . And you can access the elements with something like vect_2dim[i][j] .

And just a precision on dospy's statement. You are allowed to write and do variables[0] = 1; , but the first element (accessed by index 0) must already exist in the vector before you do this. Xide, I suggest that you take a bit of time looking at the documentation about std::vector, it's better than us trying to describe every useful function it contains.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Let me clear out some confusion about "bool". Strictly speaking, a bool value can be true or false, so, it can only take two values. Practically speaking, any integer value is implicitly converted to bool as if you wrote bool(value != 0) , meaning that any non-zero value is interpreted as a true bool value.

Storage-wise, a bool requires 1 bit of storage (0: false, 1: true) (from C++11 standard clause 9.6/3), but, because bytes are not divisible, a single bool variable will have to occupy a full byte.

The C++11 standard, at 4.5/6, says:

A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true becoming one.

And section 4.12/1 says explicitly that any conversion of an integral or pointer type to a bool type will result in false if the value is exactly zero, and true otherwise (also, null_ptr converts to false).

So, bool is not just a kind-of renamed unsigned char type and it's not just provided for convenience to the user, it is a type of its own right and it can be stored efficiently, for example, as part of a bitfield or specializations of STL containers such as std::vector which will result in requiring only 1 bit per bool variable.

Finally, bool is a very special type of integral type because pretty much any arithmetic operation on it has undefined behavior or is invalid.

That's about all you need to know …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

What you are looking for is a dynamic array container, in C++, there are many containers, the most usual being std::vector , find info on it here.

Here's a very simple example:

#include <iostream>
#include <vector>

int main() {
  std::vector<int> variables;
  int x;
  std::cout << "Enter a number (0 to quit): ";
  std::cin >> x;
  while(x != 0) {
    variables.push_back(x);
    std::cout << "Enter a number (0 to quit): ";
    std::cin >> x;
  };
  std::cout << "You entered:" << std::endl;
  for(int i = 0; i < variables.size(); ++i)
    std::cout << variables[i] << std::endl;
  return 0;
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Maybe I missed something here, but if you have a sorted sequence of items, isn't it super easy to determine the BST order of insertion? You insert the middle item (median) first, then the median of each half and the median of each quarter and so on, so forth. But, of course, if you have a sorted sequence already, wouldn't you just keep that sequence and use a binary-search algorithm on it, instead of constructing a BST? Of course, if you don't have a random-access sequence, you might want to either transfer that sorted sequence into a random-access container, or build a BST (where each indexing operation during the insertions into the BST would be in linear-time, but you only do that BST construction once).

Also, you have mentioned that the application is for looking up meshes distributed over a heightmap, that suggest a geometric structure, in which case a simple BST is probably not the best option. Typically people use binary space-partitioning techniques for that. Easy methods for cartesian spaces include BSP trees, quadtrees, octrees, or Kd-trees, and for more general metric-spaces, you can use a dynamic vantage-point tree (DVP-tree) (I implemented a DVP-tree in a day or so, it's not hard).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Ok, if you don't have the internet connection on the machine on which you want to install the compiler, then it is much more tedious to install software on Linux.

Many linux distros come with the compiler pre-installed, and I believe Kubuntu is one of them, you can first check if you have a C++ compiler by doing:

$ g++ -v

If you have internet, all you need to do is:

$ sudo apt-get install build-essential

If you don't have internet, you need to download the .deb files manually, and then install them. You can download the packages from here:
https://launchpad.net/ubuntu/natty/i386/build-essential/11.5ubuntu1
which is for Ubuntu/Kubuntu Natty (11.04) and towards a i386 architecture, for other versions or platforms, just change the names in the address (e.g. ../ubuntu/lucid/amd64/build-essential/11.4, you can search the launchpad.net webpage for "build-essential" for your platform).

Then, you cannot just download the top-level package (build-essential) because that is actually just a collection of packages and the .deb file does not include them, it simply lists them for the package manager to find and fetch from the package repositories. So, you need to look at the "Depends" section of the Launchpad website and download all the packages listed there, and then all the packages listed in the "Depends" section of those packages and so on, so forth.

To not have to download every dependency package, you can check on your Kubuntu machine if you have the given package by a …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

@Narue: >> When writing a template class, I nearly always start out with a non-template class and typedef the "template parameters" to something like int . Then after the class is working sufficiently well, I'll remove the typedefs and make the class a true template. This has proven to be an invaluable practice for me as I'm not as rigorous as I should be with TDD.

Interesting... first time I hear that, but...
The only difference I can see between that and a class template is the fact that all the code will be compiled for a non-template class (with the "int" typedef instead of the template argument), as opposed to a class template which would just compile what is used (e.g. with TDD). For that purpose, an explicit class template instantiation works equally well (e.g. making sure all the template code compiles). Also, with your method, once you turn your class into a template, don't you have to go through a bunch of code to add the "typename" keyword (for dependent types)? That seems like more trouble then just defining it as a class template in the first place, and then instantiating it fully for a few representative types (like "int", "double" and "complex<double>" if it is intended to be an arithmetic type, and so on) as a simple test of "does everything compile for different types".

I agree that it is hard to be rigorous with TDD when writing templates, just because of the combinatorial …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>Does it HAVE to be a template argument? No!

Do #defines and MACROs have to be in all upper-case? No.
Does every loop index have to be called i ? No.
Does T always have to denote a template argument? No.
Does every name have to not start with an underscore? Uh.. well yes!

In programming, there are conventions (weak and strong), there are idioms and there are rules. Using all upper-case for MACROs is a strong convention, that is, it is so wide-spread that you can't reasonably break it by either having identifiers (that are not MACROs) in all upper-case or by define a macro in lower-case. Using (i,j,k..) for loop indices or using T for template arguments is idiomatic C++, something programmers learn to recognize and it becomes an expectation, e.g., when you see (i,j,k..) you expect it to be an index or when you see T you expect it to be a value-type for a simple template. Breaking this expectation is not a "crime" against the language, but it's somewhat "immoral" nonetheless (w.r.t. to the programmers). Restraining yourself from using leading underscores for identifiers is a rule of the C++ standard, and breaking it is indeed a crime against the language (you will not get a conviction but that's no reason to do it).

My point with this is that respecting the rules of C++ is necessary but not sufficient for good quality software. Respecting conventions and idioms are important to …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Here's my opinion on it (compilers, not IDE or build-systems):

Portability: GCC (GNU Compiler Collection)
Compilation Speed: BCB (Borland C++ Builder)
Code Optimization: ICC (Intel Compiler Collection)
Usefulness of compilation warnings and errors: GCC
Debugging capabilities: MSVC 2010 (Microsoft Visual C++ 2010)
Strict standard compliance: Comeau and ICC (using the EDG front-end)

Overall, GCC is a great option and MSVC is also pretty good, expecially considering both are free. The BCB compiler is also very good but a bit isoteric (has the same back-end as the Delphi compiler, which has some visible impacts in the form of some non-standard things, but it also gives it a much better compilation speed). As for code optimization, nothing beats the Intel compilers on Intel systems, but GCC is coming close to catching up to ICC, while MSVC is still shamefully lagging behind by a significant margin (and I don't know the current status of BCB, but earlier versions used to beat both GCC and MSVC like a rented mule while almost matching up to ICC, but that is probably not the case anymore because ICC, GCC and MSVC have improved a lot since then). GCC has also improved (4.5+) a lot when it comes to compilation times (my code-base used to take about 45min to compile entirely in pre-4.5 versions of GCC, now it takes about 15min with 4.6.2 version).

tajendra commented: useful compilation +2
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Your CalcNrCases() function should take the BottlesLeft parameter by reference if you intend to modify its value as an additional output of your function. As so:

//the prototype:
int CalcNrCases(char, int, int&);

//...

//the function:
int CalcNrCases(char BottleType, int NrBottles, int& BottlesLeft) 
{
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Yeah the statement *this.__left (and with _right) is not correct, but it was a good try. Your intent was to dereference "this" using the *this and then access the member with the dot syntax. The problem is, the dot operation takes priority over the dereferencing (star). So, it can be solved with parentheses: (*this)._left . However, as a nicer version, C++ provides an operator that does this "dereference + dot" to access a data member of an object from a pointer, and it gives this: this->_left (using an arrow operator). That should solve your problem,

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

And your static data members require the class qualification:

//notice all the 'Int11::' here:
const string Int11::_author ("My Name");
const string Int11::_affiliation ("Ohio University");
const string Int11::_course ("CS240B");
const string Int11::_term ("Fall 2011");
const string Int11::_Project ("Assignment 1");

And, your operator << is missing the closing curly brace:

ostream & operator << (ostream & os, const Int11 & rhs){
        os << rhs.getString();
}; //notice '};' here.
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, you did forget the const qualifiers on four of your getXXXX functions, they should be:

T Int11::getLeft() const { //notice 'const' here.
        return (_left);
}

T Int11::getRight() const { //notice 'const' here.
        return (_right);
}

T Int11::getCenter() const { //notice 'const' here.
        return ((_left + _right)/2);
}

T Int11::getRadius() const { //notice 'const' here.
        return (((_left + _right)/2) - _left);
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>the typedef double T was in his code and he told us to use it.

That does not bode well. I seriously doubt his ability to teach C++ if he makes such beginner's mistakes.

I also don't see any "std::" qualifications, can I also assume that he told you to use a header that includes a using namespace std; statement! Sh't is piling up.

The reason why most experienced programmers never do things like using namespace std; or crazy typedefs like typedef double T; , is because, although it might work sometimes, it has a bad habit of generating weird errors in code that looks perfectly fine. That's really annoying and experienced programmers develop a certain discipline to avoid setting themselves up towards those problems. If your prof ignores those very basic rules, it's a big indication he has little to no experience in C++.

A quick way to check if the typedef is the problem, is to simply swap the include statements, as so:

#include <sstream>
#include "int11.h"

The above will ensure that the standard libraries are included before any dangerous code your prof gave you is encountered.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I can't really see the error, but you said that there is code that does typedef double T; . I don't think you grasp the ramifications of doing this! This is horrible, and very dangerous. The "T" is very very often used as a name for a template parameter. If you don't know what a template is, don't worry, just trust me when I say that they play a significant role in most C++ standard libraries. So, considering those two things (T being the most usual name for a template argument and the C++ standard libraries making significant use of templates), that makes the statement typedef double T; very dangerous and very likely to break any standard library that you include (like "sstream" in your case). I would not be surprised at all if that was (somehow) the source of your error.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

First, you keep saying "math.h", but this is a C++ forum and you are also referring to writing a class. In C++, the standard header for math functions is "cmath" (as in #include <cmath> ), the "math.h" is only kept for backward compatibility with C and pre-standard C++.

Second, when using the C++ version of math libraries, you have many advantages over the deprecated C version. The first advantage is that C++ has function overloading which allows functions like "sin()" or "exp()" to take different types of values (like float, double, long double) and provide the best implementation for either cases. The second advantage is that all the C++ math functions are wrapped in that "std" namespace, meaning that you can and _should_ invoke functions like so: std::sin() and std::exp() (i.e. the std:: part qualifies the call and asks the compiler to look for the function in the std namespace).

Finally, to solve your problem, you can simply define your versions of the math functions inside another namespace, like fast_math or some other name like that. This way, you would invoke your faster math functions like fast_math::sin() or fast_math::exp() . As so:

namespace fast_math {

float sin(float x);
//..

};

PS: Why on Earth would you want to implement those math functions as member functions of a class? That makes no sense. C++ is not about putting everything into classes (that's Java).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>There is a lot of tutorials but they are all without code example

That's normal. There is a big difference between learning a programming language and learning software design. First, you need to get familiar with the syntax and idioms of a particular programming language. And learning to create classes (including inheritance, virtual functions, constructors/destructor, etc.) is part of learning the programming language (if it has syntax to do this, of course, and C++ does). Then, once reasonably comfortable with at least one programming language that makes OO code easy to write, you can learn about OO analysis and design, and apply it with your language of choice.

It's the same with computer science textbooks / papers that show you algorithms in pseudo-code instead of actual code in one language or another, because the actual programming language matters only when it comes to the details.

If you read OO tutorials or articles and cannot figure out how the things that are discussed translate into C++ code, then it means you need to get more knowledge of C++. Object-oriented programming is a way in which you organize and think your software, it's not about how you exactly write it (that depends on the language, in C++ or Java, OOP is done essentially the same, but the details are (very) different).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Most "special" math functions (like trigo., sqrt and exp/log) translate directly into a single instruction or a few (in assembly), and the performance of those instructions depends on the hardware. Of course, this is if your system has those instructions, most non-microcontrollers have them (unless your PC is more than 20 years old). They used to be much slower than the fundamental arithmetic functions like additions / multiplications, but nowadays, that difference is much smaller.

On micro-controllers, it's a different world, sometimes floating-point arithmetic is not even supported at all, in other cases, floating-point operations are limited to more fundamental arithmetic. In those cases, you do have to resort to hand-rolled implementations (usually a series expansion and some SAS algorithm), or you have to somehow live without it.

When people decide to rewrite some of those math functions on PCs (and they do sometimes), it's usually motivated by needing performance more than robustness. Surely you can appreciate that IEEE-specified math instructions are required to be very safe, precise and predictable over the entire range of possible input values. You certainly pay a price (although fairly small) for that robustness. So, yes, it is possible to have a more efficient implementation of the math functions, but you will most likely have to give away some precision and/or range. In some specific applications (e.g. computer game programming), you need to squeeze every clock-cycle out of the processor, the precision of the calculations is usually not important (only as precise as …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>Where can I get more detailed information on this subject ?

This article is pretty good on rvalue-refs, its minimalistic, but it's all you really need to know.

Otherwise, for general C++11 info, just use the wiki (rvalue-ref is the first section).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, it is certainly useless to do it this way, but if you do, then yes, the compiler will optimize this away. If it doesn't, then it is a very pessimizing compiler (pessimizing = anti-optimizing). All modern compilers do this.

In general, the rule of optimizations is the "as if" rule, that is, the optimized code should behave as if it was the verbatim translation of the original code (i.e. not optimized in any way). However, there are two notable exceptions to this rule, that is, elision of temporaries and return-value optimization. The former means that if a temporary is created and immediately copied into another variable, then it can sometimes be optimized away (but it depends on the context). The latter means that the value that is returned from a function can be created in-place of the variable it is going to get copied to (again, under some circumstances).

Because, in C++, you can execute code during the constructors/destructor of an object, it means that optimizing away the creation of a temporary object technically breaks the "as if" rule. But, because those optimizations are so important for performance, the C++ standard allows it, and all decent compilers take advantage of this permission. So, this is something to keep in mind when writing constructors/destructor code, that is, you can't really predict how many times they will be called, all you can rely on is that anything that is created is eventually destroyed (i.e. every constructor call will eventually …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

A pure (or minimal) stack implementation would just provide a few functions: usually just one to push a new element to the top of the stack, one to read the top element of the stack, one to pop the top element off the stack, and a function to tell if the stack is empty.

I also think that the question is a bit weirdly formulated but my guess is that what is asked is for an algorithm that can print all the elements of a stack (Astack) while leaving it unchanged. Now, the problem is that since you can only read the top value on the stack, you can't really "traverse" it without popping elements off the stack until it's empty. So, the problem is this: how can you manage to repopulate the stack with all the same elements it had before? That's where the Bstack comes into play.

Just imagine that you had a pile (or little tower or stack) of blocks (like those blocks with letters on them like you used to play with as an infant) and you could only see the block that is on top. If you wanted to know all the blocks that are in the pile but you wanted to restore the pile to how it was before. If you just carelessly take all the blocks off, you would have no idea in which order to put them back, so that's not an option. If you carefully take notes to mark …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You wrote "List" instead of "list", C++ is a case-sensitive language.

Because the compiler does not recognize the "List" as a type (and thus starting a declaration of a parameter-list), it thinks that line 12 is a declaration (and initialization) of a "variable or field" called "start" and because it sees it as a "void" type, it gives a compilation error.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I think that the only problem with your code is that the bound on the for-loop should be the variable "bound", not the variable "sum". You had this:

for(i = 1; c <= sum; i++)

I think you should have this instead:

for(i = 1; c <= bound; i++)
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The multimap class includes a function, called equal_range, which returns the range (as iterator pair) of elements of the multimap that have the same key. Finding the number of elements with the same key is simply a matter of counting the elements in that range.

If your purpose is to construct a graph of some kind, you might want to take a look at the Boost.Graph Library (BGL) which has all sorts of graph / tree containers and algorithms.