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

The code I posted works on C++03 (with Boost) (but, as always, it could not work on MSVC compilers, especially prior to 2008, because MSVC is just crap when it comes to template support).

And I have checked in C++0x standard (latest draft), and the rules for partial specialization will not change at all (not even for function templates!).

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

Oh.. sorry, you're right. You can't do a partial specialization of only a member function (but you can do a full specialization). This is one of those annoying C++ template rules ("The members of a class template partial specialization are unrelated to the members of the primary template").

I should have known, I just answered a question on SO about this specific problem. To avoid having to redefine all the member functions for each partial specialization, the solution, besides using a mixin pattern, is to use a Sfinae method. As such:

#include <iostream>
#include <boost/utility/enable_if.hpp>
#include <boost/config.hpp>

template <typename T>
struct is_int { BOOST_STATIC_CONSTANT(bool, value = false ); };

template <>
struct is_int<int> { BOOST_STATIC_CONSTANT(bool, value = true ); };

template <typename T, typename U>
struct Point {
  void function1() { };
  void function2() { function2_impl<U>(); };

  template <typename B>
  typename boost::enable_if< is_int<B>, void>::type function2_impl() {
    std::cout << "'int' partial specialization" << std::endl;
  };

  template <typename B>
  typename boost::disable_if< is_int<B>, void>::type function2_impl() {
    std::cout << "primary template" << std::endl;
  };
};

int main() {
  Point<float,float> a;
  Point<float,int> b;

  a.function2();
  b.function2();
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

There are no freebies here. We can help you if you show that you have done some efforts of your own and if you are stuck on some specific problem(s). Don't expect to just ask and get people to solve your homework assignments. That wouldn't be helpful to you, nor would it be righteous.

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

setprecision only affects the next write operation. So you can setprecision on the numbers you want to have a fixed precision on and don't use it for those that you don't want precision on.

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

>>so does this mean that I indeed must partially specialize EVERY class member?

Yes. What you are doing is specializing the entire class, it redefines it completely, so function2 does not exist in the partial specialization unless you redeclare it. But you can specialize the member only (here is a good article):

template<typename T, typename U>
class Point<T, U>
{
  void function1();
  void function2();
};

template<typename T, typename U>
void Point<T, U>::function1() { ... };

template<typename T, typename U>
void Point<T, U>::function2() { ... };

template<typename T>
void Point<T, int>::function1() { ... specialization ... };

PS. auto_ptr has been deprecated by unique_ptr.

daviddoria commented: As always, an excellent response! +5
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You need to omit the specialized type from the template <...> declaration. See my edit on your example. As here:

template<typename T>  //the types in here are only those that are unknown.
class Point<T, int>
{
  void function1();
};

//similarly:
template<>  //no type is unknown (full spec.) but you still need this.
class Point<float, int>
{
  void function2();
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Don't use setprecision if you want the computer to figure out the precision.

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

**Please use code tags**

>>int findDuplicate(string a,string b)

In C++, strings can be compared with ==. There is no need for this function.

>>int i,j=0,flag=0;

Declare your variables where you first use them, whenever possible.

>>for (i=0; i<(int)stringTable.size();i++)

Prefer iterators to indices when doing a simple linear traversal:

for (vector<string>::iterator it = stringTable.begin(); it != stringTable.end(); ++it) {
  temp2 = *it; //you don't really need temp2, just use *it everywhere instead.

>>i guess sort n unique cannot be used for vectors.....

They certainly can, that's what they are for, mostly used with vector (or some other STL containers). Just see the example for std::unique.

Hint: Using a set instead of a vector is probably the easiest way to do this (although using "sort" and then "unique" is arguably more efficient). You can even write almost the entire program in one line (but that's going a bit too far).

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

The error comes from the fact that declaring a variable as extern does not "declare" the variable, it simply tells the compiler that there is a global variable with that name. Somewhere, you need to have a global variable with that name. You don't have that anywhere. You could just put a "int random = 0;" somewhere in the global scope (outside any function body). However, I really don't get the point of your implementation, the random variable will never change because rand_gen() is never called.

This is probably the implementation that makes more sense:

#include <cstdlib>
#include <ctime> //use ctime, not time.h
 
#ifndef RANDOM_H

struct rand_var{
	int x,y;
}Rand_var;

struct Rand_seeder { Rand_seeder() { std::srand((unsigned)std::time(NULL)); }; };

inline int rand_gen() //use the inline keyword here, not static.
{
	static Rand_seeder rs; //will seed the random number gen. only once.
	return rand() % (Rand_var.x-Rand_var.y+1) + Rand_var.x; //use a return value.
}
#endif /* random.h */

Then you call rand_gen every time you need a new random number in that range that you have (also, having this range thing as a global variable is pretty bad too).

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

Where is the copy-constructor in your Mascota class? That's the piece missing, and what an important one!

I highly, highly recommend that you use std::string instead of char* and that you store the integer edad by value, not by pointer. Pointers are evil and you are suffering it right now.

If you choose to keep pointers, there are a few errors in your code. First, your assignment operator does not check for self-assignment (which will cause a seg-fault as it is now). You should add a if(this != &x) to check for self-assignment. Better yet, use the copy-and-swap idiom.

Finally, your Set() function does not delete the old pointers before you reallocate memory.

flowerzink commented: Helped me solve my problem +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Definitely, it is the comparator that is not correct. It should be (strcmp() == 0) (strcmp returns 0 if the strings are equal). If you used a std::string, it would be even simpler.

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

Yes, that will allow for the call to happen, but there is still the question of valid data. The cast takes away the guarantee that the value will be correct. I guess that it depends on the situation which is more appropriate.

Sure. That's another reason why casts are not desirable. The OP could also define a custom conversion function:

enum color { red = 0, green = 1, blue = 2 };

color to_color(const std::string& s, color default_value = color::red) {
  int i;
  std::stringstream(s) >> i;
  if((i >= 0) && (i <= 2))
    return static_cast<color>(i);
  else
    return default_value;
};

But that puts overhead. It's a matter of choice really, safety or performance. There is no way to convert an int whose value is determined at run-time, to an enum type without having to make that choice.

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

Casting from int to enum just requires an explicit cast (it is meant to reduce unintentional (implicit) casts). Just use a static_cast. As so:

display.setMode(static_cast<VideoOutputMode>(atoi((**vout_mode).c_str())));
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Glad to help!

To answer your questions:

>>Is the ordered list above Ok? if not please add; :-)

It seems good to me. You probably should interleave it with "Challenge yourself and do cool things that are interesting to you". That pretty much fits in-between each point on that list. It is very important for sustained interest and to learn by experience. It is by making mistakes (like the bugs you had in that code) that you learn the value of certain techniques (like RAII and const-correctness in this case).

>>With consistency and dedication, is it possible to realize these in 2 months all on my own?

With consistency and dedication I realized those things after several years. Read this article for example. This pretty much applies to me, but I also did many mistakes (what I like to call "reinventing the wheel, making it square and breaking your back using it"). Never say "I know best", always look around at what is available and how people solve certain problems before tackling them yourself, it will avoid you a lot of pain and should speed things up.

>>...thinking I've almost arrived! till I realized there is never an end to programming!

Isn't that the fun part? You can never stop learning and improving as a programmer, never. Every year since I have started programming, I can look back at the stuff I programmed a year before and be disgusted by the …

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

Well, do you really have that many alternative strategies? For a test program like this, I don't see much alternative to just listing out the combinations and executing them one after the other.

Anyhow, you could just make f, g, and h as static arrays of boost::function<> and loop through all of them (three nested loops). For instance:

int main()
{
 boost::function<....> f[] = { boost::bind(.....),
                               boost::bind(.....),
                               boost::bind(.....) };
                               
 //similarly for g and h.
 
 for(int i = 0; i < sizeof(f); ++i)
   for(int j = 0; j < sizeof(g); ++j) 
     for(int k = 0; k < sizeof(h); ++k)
       someCode(f[i], g[j], h[k]);
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>What kind of bug do you classify the program's problem into?
const-correctness.

>>I plan to integrate a UI and upload it on sourceforge if I can
It's good to do these little projects as learning experiences, but don't mislead yourself into thinking that this kind of code would be worth anything to others. For instance, the Boost.Date-Time library is much more feature-rich and professionally implemented. Sorry for this, but the truth is better than wishful thinking. But keep up with it, as a learning experience.

Now, for my (constructive) remarks on your code:

- The Timer class is not a time, it has records of time. This means that inheritance is misplaced here. Timer should not inherit from Time. It should contain time records, which it does and that is good.

- Don't use dynamic allocation when it is clearly not necessary. You Timer class holds the Time records via pointers that it deletes upon destruction. That is very wrong. There is no reason, as far as I can see, why they could not be held by value. As it is now, you have a bug because you did not respect the rule of Three in C++. The compiler is going to supply the Timer class with a default implementation of the copy-constructor and assignment operator which will both be problematic since they will do a simple copy of the pointers (not of the pointed-to objects). When two copies of a Timer …

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

>>what if some of the functions in the code depend on that symbol?

If the OPs code is not using the code in a way that requires this "thread" #define, it should be fine. In other words, if the use of this keyword is only restricted, in the code, to the other library's header files, it should be fine. Otherwise, he will have to play a little game of #defining and #undefining the keyword around every use of it. I'm pretty sure it will be Ok.

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

Well, first of all, my recommendation would be to throw away that incredibly stupid library that does this. I can't comprehend how retarded somebody must be to think that making a #define with the name "thread" is not going to cause tremendous name-clashes.

Anyways, if you really have to use it, you can undefine the define after including the other library. As so:

#include "other_stupid_library.h"
#ifdef thread
#undef thread
#endif

#include <boost/thread/thread.hpp>

//....

That should solve your problem.

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

Normally, you do need to lock both the reader and writer such that their operations are mutually exclusing (with a mutex or critical section(windows), personally I would recommend Boost.Thread since it uses the best mechanisms for whatever OS you use). And, if you lock all read and write operations, then there is, of course, no issue with having multiple readers and multiple writers. But be careful not to introduce deadlocks. Also make sure you don't lock for more time than needed, because you can easily destroy performance (i.e. you end up with a number of threads lined-up, sleeping, when they could be doing useful work).

You probably also want to use a condition_variable to wake up the reader when a new element is available (in fact you can use the same mutex in the condition_variable). This is going to avoid needless decisions on how to poll for new elements to read (do you use a tight loop that repeatedly checks for new elements, or do you sleep X amount of time between checks). The condition_variable will allow you to put the reader thread to sleep until the queue has a new element.

Finally, if this is anywhere near to being a performance-sensitive implementation, then there are alternatives that allow you to avoid locking (almost) completely. This article presents a nice and simple lock-free queue implementation. Operating systems often rely on a form of RCU to have lock-free readers in a single-writer / multiple-readers problem.

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

The find function returns a const_iterator in the map, you have to check that it is valid and then output it, and you also have to deal with the fact that the iterator might be invalid if the element does not exist in the map.

const std::vector<passenger*>& passenger_queue::passengers_at_floor(int floor_) const
{
  std::map< std::vector<passenger*> >::const_iterator it = _waiting_passengers.find(floor_);
  if(it != _waiting_passengers.end())
    return *it;
  else
    return std::vector<passenger*>(); //or throw an exception.
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

My rule of thumb to decide whether to use free functions or class member functions is as follows. First of all, if you need to keep track of a state of some kind (like an opened file or array/vector or any other construct like that), then you need a class to hold that state (in your case, a Log class), that's a given. Now, the question is whether you should implement the functionalities as part of the class (as a member functions) or as free functions (alongside the class, but not static members, nor necessarily in the same header file). My rule is simple, if the main operation that a particular function does is to work on the class data members, then use a class member function, use a free function otherwise.

So, this means any get/set is obviously a class member. It includes typical things like you see in STL containers (like insert, erase, find, swap, clear, resize....) which clearly directly affect the internals of the STL container and is not meant to do much of anything else.

But then, there are things like operators. Obviously, some have to be members (like assignment and += and such, and some other special ones). But others don't, like addition or multiplication, these clearly act as much on one object as they act on the other, so they probably sit better as friend functions (in fact, because of overloading rules, they really ought to be friend functions and not members).

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

yep that's the gist of it.

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

I think that the easiest way to do it is to simply use a functor with both overloads. Something like this for example:

struct adaptSR_type {
  typedef int result_type;

  template<typename accStrategy>
  int const operator()(int const MAX_AL, float const CONFIDENT_LV, int const OFFSET, accStrategy PLAN)
  {
    return 1; 
  }

  int const operator()(int const MAX_AL, float const CONFIDENT_LV, int const OFFSET)
  {
    return 1;  
  }
} adaptSR;

template<typename T>
void testArg(T haha)
{
  int const MAX_AL = 10;
  float const CONFIDENT_LV = 10;
  int const OFFSET = 10;
  haha(MAX_AL, CONFIDENT_LV, OFFSET);
}

int main()
{
  float a = 3;
  testArg(boost::bind(adaptSR, _1, _2, _3) );
  testArg(boost::bind(adaptSR, _1, _2, _3, a) );
}

Of course, your template overloads have to be callable without explicit template arguments, so you need to make sure they can be deduced from the parameter types. And if you need to use explicit template arguments, you can simply make the functor a class template. I think that solution makes it a lot nicer on the user-side code.

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

>>A dinosaur will pop out of your computer and eat you if you do.

I wish it could be required by the C++ standard to devour any programmer who writes a "goto" statement.


>>I don't understand why goto's are so bad.

A goto statement is a relic from the times when most programmers where used to programming assembly code (which relies, of course, on labels and jumps (i.e. gotos)). There are many programming paradigms (functional prog., procedural prog., object-oriented prog., imperative prog., declarative prog., generic prog., meta-prog., etc. etc.), by far the worse of them all is "spaghetti coding", and that is what gotos are "useful" for. All other paradigms are based on some sort of logic, "spaghetti code" is not. For example, in procedural prog. ("C-style"), a program is basically a sequence of state transitions (like a FSM), the state is all the variables of the program and the transitions are the functions. The logic behind it is that each function should require some pre-conditions (the state of its inputs), and produce a predictable post-condition (outputs). Then, the act of coding in procedural programming is all about putting the right sequence together (and branches, of course). Most other (high-level) paradigms are built on top of this fundamental logic. The goto statement is an explicit violation of this procedural prog. logic by jumping discontinuously across the sequence of transitions. It is, in itself, a maintainability nightmare. Any trivial use of a goto-statement can easily be …

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

Oh, that's right, if you use a std::map, the operator[] does not exist in the const form because if the index (or key value) does not exist, a new element will be created. So, for the const version, you need to use the find() function instead which will just find the element corresponding to a key (or an invalid iterator if the key does not exist).

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

The error you got is expected. A static array requires a value that is known at compile-time. You cannot let the user choose the size, because that implies that the size would be determined at run-time. The solution: use a dynamic array.

The easiest, in C++, is to use std::vector (#include <vector>). Then, you can declare it as follows:

class tempHolder{
  public: 
    int icol, irow;
    std::vector<bool> C1;
    tempHolder(int numCols, int numRows) : icol(numCols), irow(numRows), C1(numCols * numRows) { /*initialize C1 to whatever you want*/ };
    //no need for a copy-constructor or assignment operator.
    //... the rest of your functions.
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

In the snippet I showed, I made a mistake, it should be static_cast and not reinterpret_cast (sorry), to turn a void* into a T* properly. That is also a _downcast_ (because void* is an implicit base pointer type for all pointer types in C++, that's inherited from C). In practice, a reinterpret_cast also works equally (but is technically not guaranteed to work the same, based on the standard).

>>am i to use an explicit cast for upcasting or will the implicit cast suffice?

Upcasting pointers is always implicitly done and there is no need to use a static_cast operator to do so. But, of course, you can always use a static_cast just for making it obvious that a cast is made (instead of hiding it in an implicit cast). But, of course, it makes no difference in execution.

One very important rule: Do not use a "reinterpret_cast" to do an upcast or a downcast of pointers between two non-void types (even if they are related in a hierarchy). There is a big difference between reinterpret_cast and static_cast, they should not be confused. In my example, it is ok because the pointer returned by the func() function was just cast from T* to void*, so it is safe to cast it back to T*. This is the only acceptable use of reinterpret_cast with pointers, i.e., to temporarily cast a pointer to void* and immediately cast it back to its original type. That is guaranteed to work and is …

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

No. ICOL is not a global variable, it is a #define. A #define is basically just a token (i.e. ICOL) and an expression (i.e. 32). Basically, the preprocessor (a basic parser that looks at your code before it gets compiled) will look through all the code and do a basic find-and-replace operation, finding each instance of ICOL and literally replacing the ICOL by 32 directly in the code, then the code gets compiled. So, doing ICOL = 300; would be the same as doing 32 = 300; which is obviously an error.

To create a global variable, you do this:

#include <iostream>
using namespace std;

int icol = 32;

int main(int argc, char *argv[]) {
  icol = 300; //ok!
 //...

As a note, it is rarely desirable to have a global variable that can be changed (it is bad practice). And make sure your global-variable names are always very unique (they could clash with other variable names in the std namespace for example).

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

You can also create a composition of small POD classes (Plain Old Data) for the data that some components might have in common, instead of an awkward inheritance scheme.

As I understand it, slab and beam are really two different types of objects, but they share common type of data. For example, say they both have, as defining data members, x-y coordinates for the end-points, and maybe some material properties (stress-strain, yield point, Poisson ratio, Young's modulus, etc.) (assuming you are doing some sort of structural analysis). Then, inheriting one from the other or vice-versa is not really meaningful, but creating small classes that handle a small subset of the properties is much easier, and they can have all their data members public. For example:

struct LineSegment {
  double start_x, start_y;
  double end_x, end_y;
  void get_data(istream& in) {
    in >> start_x >> start_y >> end_x >> end_y;
  };
};

struct Material {
  double yield_stress;
  double E, mu;
  void get_data(istream& in) {
    in >> yield_stress >> E >> mu;
  };
};

class Slab : public Component {
  private:
    LineSegment geom; //has a "line-segment" geometry, but is rigid (not material)
    //... other data members...
  public:
    void get_data(istream& in) {
      geom.get_data(in);
      //get data for the other data members..
    };
};

class Beam : public Component {
  private:
    LineSegment geom; //has a "line-segment" geometry.
    Material mat;     //has a material that characterizes its deformability.
    //... other data members...
  public:
    void get_data(istream& in) {
      geom.get_data(in);
      mat.get_data(in);
      //get data for the other data members..
    }; …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

This is very weird. The problem must be a sort of stack wind-up of the for-loop (at low-level a for-loop is turned into a "label, set of instructions, and goto the start label", so if "set of instructions" increases the size of the stack you get a stack wind-up). But this is a bug, not an expected behaviour.

Try to increase the level of optimization, maybe the compiler can get rid of a useless temporary and thus, solving the problem at the same time. For instance, if I compile your function with highest level of optimization with GCC, it turns out that it eliminates the entire run() function because the compiler is clever enough to see that this function has no effect (it only modifies a local variable and returns nothing).

What compiler are you using? Have you tried alternative compilers? Make sure the one you have is recent and appropriate for your system.

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

It's totally fine. In fact, it is a safe way to do it. But it is kinda useless as is, because if the caller has access to the vtable pointer (to look up the virtual call to func()), then it can also implicitly cast the object pointer or reference to a pointer or reference to the base class A. Also, overriding the func() in class C is useless because the implementation in class B is already sufficient and can be reused.

Nevertheless, a very similar technique can be used to perform downcasts (to substitute for the dynamic_cast operator). This is a classic example:

struct A  {
   static const int myID = 1;
   virtual void* func(int aID) { 
     if(myID == aID)
       return this;
     else
       return NULL; 
   };
 };

struct B : public A  {
   static const int myID = 2;
   void* func(int aID) { 
     if(myID == aID)
       return this;
     else
       return A::func(aID); 
   };
 };

struct C : public B  {
   static const int myID = 3;
   void* func(int aID) { 
     if(myID == aID)
       return this;
     else
       return B::func(aID); 
   };
 };

template <typename T, typename U>
T* my_dynamic_ptr_cast(U* obj) {
  return reinterpred_cast<T*>(obj->func(T::myID));
};

int main() {
  C objC;
  A* ptrA = &objC;
  C* ptrC = my_dynamic_ptr_cast<C>(ptrA); //downcast of a pointer to A to a ptr to C.
  std::cout << "Pointers are: " << ptrC << " " << &objC << std::endl;
  return 0;
};
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The printf function is not type-safe (it is from C, which is only weakly typed). The printf interprets its parameter types (after the formatted string) based on the format values in the string. So, if you have %d in the string, it will interpret whatever the second parameter is as an int, regardless of what type it actually has. So, if you pass a pointer (void or other-wise), it will print-out whatever address is stored in the pointer.

When you call fun(), at lines 10 and 11, you are also doing a type-unsafe conversion (C-style cast). Using this (int*) cast is going take anything (and I mean _anything_) and blindly assume its value is the address of an int variable. So, in the first version it assumes the value of the char is an address of an int (in fact, it will assume that the 1 byte of the char is 1 byte out of 4 or 8 bytes that represent the pointer, it just happens that the other 3 or 7 bytes in memory are zero, but that's just luck). So, in the first case, you get the value of the char printed out, while in the second case, you get the address of the char printed out.

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

This function:

std::vector<passenger*>& passenger_queue::passengers_at_floor(int floor_) const

Has a big flaw, which results in the error you are getting. Since the function is const, it means that you only have read-only access to all its data members. But then, you try to return a non-const reference to a data member from that function. This simply cannot work, and hence, the error you get (either you put the const at the end and you get a "discards qualifiers" on the return type, or you don't put the const and you get a "discards qualifiers" on the this pointer when the function is called). The solution is simple, define both versions:

//make a non-const function that returns a non-const reference: 
std::vector<passenger*>& passenger_queue::passengers_at_floor(int floor_);
//make a const function that returns a const reference:
const std::vector<passenger*>& passenger_queue::passengers_at_floor(int floor_) const;

Both implementations of the above functions are exactly the same. When you call the function with a const object, the const function will be called and a const reference will be returned (and vice-versa if called with a non-const object). This is the proper, and usual way to do this.

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

There are two fundamental ways to do this (at least what I can understand of it, I think a more concrete example would be better): Composition and Inheritance.

In the case you presented first (with A, B, C, and D), I think inheritance seems most appropriate (although the example is far to vague to really tell). You could do this:

class A
{
/*Variables required by A, B, C and D */
/*functions required by B and C*/
};
class B : public A
{
/*some of it's own functions and variables*/
};
class C : public B
{
/*some of it's own functions and variables*/
};
class D : public C
{
/*calls all the functions in A, B and C*/
};

With this, all the things you described inside the comment blocks should be easy to do.

**EDIT**
Or as AD posted, a diamond inheritance is another possibility:

class A
{
/*Variables required by A, B, C and D */
/*functions required by B and C*/
};
class B : virtual public A
{
/*some of it's own functions and variables*/
};
class C : virtual public A
{
/*some of it's own functions and variables*/
};
class D : public B, public C
{
/*calls all the functions in A, B and C*/
};

********

However, you have to realize that these design decisions are not and should not be driven by what you (think you) need, but by functionalities that …

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

>>it seems like a sh*t load of code for nothing more but switching tenants.

Well, you could merge the two loops and merge the nested if-statements. Also, note that (_assignments[i][j] != NULL) is equivalent to (_assignments[i][j]) in an if-statement. So, you get:

//finding indices for first tenant
  for (int i = 0; i<_floors; i++) {
    for (int j = 0; j<_rooms_per_floor; j++) {
      if (_assignments[i][j]) {
        if (_assignments[i][j]->get_id() == first_tenant_) {
          ft_one = i; rt_one = j;
          found_t_one = true;
        } else if (_assignments[i][j]->get_id() == second_tenant_) { 
          ft_two = i; rt_two = j;
          found_t_two = true;
        };
        if( found_t_one && found_t_two )
          break;
      }
    }
  }
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

When the const is at the leftmost place, it is attached to the return value. In that = operator, it means that the function returns a const reference to itself.

When the const is at the rightmost place (after the parentheses), it is attached to the object to which to member function is called on (i.e. the this pointer). This means that the object and its data members cannot be modified in the body of the function.

The error you get is from the fact that when you have a const object, you can only call const member functions on it (with the const at the end), to guarantee that it will not be modified.

For the = operator, you cannot put it as const (at the end) because, by definition, the assignment operator will modify the data members within the function (i.e. to assign new values to them). Similarly, your [] operator is wrong. If you declare it const (at the end), you cannot return a non-const reference to one of its elements, so typically, it is implemented as follows:

const T& operator[] (int i) const   //takes a const "this" and returns a const ref.
    {
      return component[i];
    }
    T& operator[] (int i)      //takes a non-const "this" and return a non-const ref. 
    {
      return component[i];
    };

The difference between returning a const reference and a non-const reference in the case of the assignment operator is that if you return a non-const reference, the following would …

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

>>they could be solve at compile times?

Well, it goes without saying that you have to turn on all the optimizations (-03), and hope for the best. Inspecting assembly listings (with option -S ) is the way to check it out (but you have to know assembly though..).


>>But according to the link at below, looks like this is not a common technique between those compiler vendors yet

Yes, of course, compilers don't support C++0x yet (it is not yet the standard after all). When it comes to early feature-full support, only GCC really matters. The other vendors are historically bad at keeping their compilers standard and feature-full. The only other exception is probably Comeau. I would guess that ICC won't take too long to comply either (especially for all the concurrent programming features). I would be surprised if the MSVC compiler gets to full compliance with C++0x by the time the next standard after that is coming out (circa 2016+), since only the 2010 version is of decent quality with respect to C++98.

I personally use GCC 4.6.0 experimental (that I compile from source on roughly a monthly basis), this guarantees as much C++0x support as possible and fast template meta-programming compilations. But otherwise, version 4.5.2 is pretty good too and is available on most platforms as binary distribution.

BTW, without variadic templates, you can still do the manual coding for each different number of arguments (up to maybe 10 or something …

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

I think that a good old dictionary can give you a pretty good start: "auxiliary" and "helper" are synonyms in English. And, as far as I know, they are synonymous in programming terminology as well. "Utility functions" are similar in some sense but slightly different.

A "nonmember" function is obviously in opposition to a member function. A member function belongs to a class, i.e., tied to the class. By opposition, a nonmember function is not tied to a class, i.e., it is "free". So, "nonmember function" is a synonym of "free function". The only reason one might use the "nonmember" term is to emphasize the contrast to a member function, e.g., you might hear things like "this kind of operator should be a nonmember function" (to emphasize a case where it is better to define the function outside the class, when both are possible).

So, we are down to two main concepts: "free functions" and "helper functions". Are they the same? No. A helper function, as its name implies, is there to help, which means that it does not do something useful by itself, but rather helps another function to do something. Very often, especially with more complex algorithms, there are sub-problems that the algorithm solves many times in a loop and that sub-problem is not really useful to the user, but it is useful to a few other variants of the same algorithm. Then, that sub-problem can be put in a "helper function" to be used by …

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

>>an object with no members, what will it's *this point to in memory if it has no member variables/attributes?

The standard requires that even empty classes should have a non-zero size. So, it does point to some amount of allocated memory, it's just that that memory is meaningless (i.e. just a placeholder for the object). And the this pointer has to be passed to a non-static member function, whether the class is empty or not.

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

>>is there any additional overhead for the first case?
Yes, of course. In the first case, you needlessly create an instance of the Log class. And then, when you call the member function, the this pointer is implicitly passed as a first "hidden" parameter to the function, so that's a small additional overhead. In the second case, neither of those things happen and thus, it would be more efficient (not to mention that if createLog() does not need a Log object to work on, then, it is, semantically, more appropriate for createLog() to be a static function).

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

The non-copyable is implemented as follows:

private:
    building& operator= (const building& other); //notice & at return and no {}
    building (const building& other); //notice no {}

If the above triggers a compilation error, then it means that some part of your code (from where the error was triggered) does indeed do a copy of a building object, which is incorrect. I think you should post all the code for the building class. I'm sure the error will be obvious (to an experienced programmer).

fibbo commented: patient and very helpful. gave me some good tips. would instantly return the favor if i could! +1
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The Big Three is mostly important for any class that holds resources allocated from the heap (with new). So, it is most important for the "building" class. The person class, I would imagine, does not hold any dynamically allocated array via a pointer.

You should first try to make the building class non-copyable (by declaring the copy-constructor and assignment operator private and without an implementation).

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

>>Are those recursive call also finish in compile times too?

You will find two types of recursive use of variadic templates:

Recursive Template Instantiations: This is when the template arguments are used to recursively instantiate templates of itself (with fewer arguments). For example, the tuple implementation:

template <typename Head, typename... Tail>
class tuple : private tuple<Tail...> {
  //...
};

These are unrolled at compile-time and become a single "normal" class.

Recursive Function Template Calls: This is the case for example, of the type-safe printf() function that uses variadic templates. It will call itself with fewer and fewer parameters until there is just the string parameter. These are calls will cause a recursive instantiation of all the "child" function templates. Afterwards, it is just like a collection of "normal" functions which are subject to the same optimization rules about inlining functions and unrolling recursive calls. It is fairly likely that simple functions with no state and that satisfy tail-recursion to be turned into just one function. Otherwise, it is just like any other recursion, they will cause stack a wind-up if the compiler cannot do anything about that. But, since these functions are likely to be single-serving, it is likely that the compiler will inline them.

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

>>What is the cost about it(compile time, runtime or both)?

Compile-time: The usual costs of using templates (some code bloat, cannot be precompiled, some increase in compilation time just to resolve the appropriate template instantiations). But, variadic templates are, I imagine, easier for the compiler resolve than the equivalent template code from the current standard C++98.

Run-time: None. (at least, no more than the equivalent hard-coded, non-templated version)

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

>>On the >> issue, it did compile (used xcode and g++ via terminal - I'm on a mac atm).

It is possible that your compiler accepts this >> use. It's just that many compilers don't accept it currently. The upcoming standard will fix that little problem and require that compilers compile the >> correctly in this use-case. But the current standard prescribes that this should not compile (but since it is more of a little annoying syntax glitch in the standard, many compiler makers choose to ignore that requirement).

>>its just strange then that my compiler never said anything about it - or what am I missing?

The leading underscore (and double underscore anywhere) is clearly stated in the standard as being reserved for compiler-specific things. The reason why the compiler will not complain is because the compiler compiles all the code, without distinction of what code is from a standard library it provides (like #include <something>) and user-code. The standard reserves the leading underscore for things that are used/provided by compiler-specific implementations in its standard libraries.

>>Should I go and tell the professor/teaching assistant about the leading underscore?

Yes. You can refer them to section 17.4.3.1.2/1 of the C++98 Standard, which states:

C++98 Standard section 17.4.3.1.2/1: (Global names)
Certain sets of names and function signatures are always reserved to the implementation:
— Each name that contains a double underscore (_ _) or begins with an underscore followed …

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

>>thinking about it made me come up with this. could this work?

Yes it does. (well, you are missing one closing parenthesis)

But, there is a better way. The problem with your implementation is that you are doing a lot of useless copying (you create a "large" vector and push it to the _assignments vector). You should try to favor pre-allocation whenever possible, like so:

_assignments.resize(number_of_floors); //preallocate for the number of floors
for (int i = 0; i<number_of_floors; ++i) {
  _assignments[i].resize(_number_of_rooms); //resize each vector to the number of rooms.
  for (int j = 0; j<number_of_rooms; ++j)
     _assignments[i][j] = NULL;           //you should also set everything to NULL.
}

Also, this line:

std::vector<std::vector<person*>> _assignments //this represents the building

Should not compile for two reasons. First, you are missing the semi-colon at the end of the line. Second, when you have nested < > declarations, you need to leave a space between the > > signs, otherwise, the compiler interprets those as the operator >>

One final and important note: It is forbidden, in C/C++, to use a leading underscore in an identifier or any occurrence of a double underscore. These special names are reserved for the compiler for special purposes and cannot be used by the programmer. So, you need to change your habit and get rid of the _ at the start of the names. You can use either nothing at the start, or an "m" for "data member" (I often also use a leading "a" …

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

You should bundle the string and CGameSlot into a struct and make a list of those. Then, you can define the < operator such that structs are compared by the string. For example:

struct Struct1 {
  string User;
  CGameSlot PlayerSlot;
  Struct1(const string& aUser, CGameSlot aPlayerSlot) : User(aUser), PlayerSlot(aPlayerSlot) { };
  bool operator < (const Struct1& rhs) const { return User < rhs.User; };
};

Making a list of the above will allow you to do a sort afterwards by just calling sort() on the list of Struct1 that you generated. To push the elements on the list, you can construct them with:

list<Struct1> my_list;
  for ....
     if ...
       ...
       my_list.push_back(Struct1((*i)->GetName(), SID));
  ...

  my_list.sort();
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

This actually depends on the architecture of the processor. For x86 and x86_64, all primitive types of 64bits or less guarantee that read/write operations are atomic (meaning they cannot be interrupted half-way by a context switch). At least, it is a pretty safe assumption. You can also use CAS (Compare-and-swap) to ensure integrity. But, frankly, I think locks are overkill for primitive types. You can always use platform-specific atomicity functions and a CAS, and you should be pretty safe.

As for this little thread_safe_var, here is the working version I cooked up:

#include <iostream>
#include <boost/thread/thread.hpp>
#include <string>

template<typename T>
class lockable_var {
  mutable boost::mutex mut;
  T value;

  class const_lock_impl; //forward-decl
  class lock_impl {
    private:
      mutable boost::unique_lock<boost::mutex> l;
      T* ptr;
      lock_impl(const lock_impl& rhs) : l(), ptr(rhs.ptr) { l.swap(rhs.l); };
      lockable_var<T>::lock_impl& operator=(const lockable_var<T>::lock_impl&); //non-assignable. 
    public:
      friend class lockable_var<T>;
      friend class const_lock_impl;
      explicit lock_impl(lockable_var<T>& tsv) : l(tsv.mut), ptr(&tsv.value) { };
      operator T&() const { return *ptr; };
      T& value() const { return *ptr; };
      const lockable_var<T>::lock_impl& operator=(const T& val) const { *ptr = val; return *this; };
  };
  class const_lock_impl {
    private:
      mutable boost::unique_lock<boost::mutex> l;
      const T* ptr;
      const_lock_impl(const const_lock_impl& rhs) : l(), ptr(rhs.ptr) { l.swap(rhs.l); };
      lockable_var<T>::const_lock_impl& operator=(const lockable_var<T>::const_lock_impl&); //non-assignable. 
    public:
      friend class lockable_var<T>;
      explicit const_lock_impl(const lockable_var<T>& tsv) : l(tsv.mut), ptr(&tsv.value) { };
      const_lock_impl(const lock_impl& rhs) : l(), ptr(rhs.ptr) { l.swap(rhs.l); };
      operator const T&() const { return *ptr; };
      const T& value() const { return *ptr; };
  };
public:
  typedef const lock_impl& lock_type;
  lock_impl lock() { return lock_impl(*this); …
pseudorandom21 commented: +1 for excellence in daniweb-ness. +1
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Are you sure that this line:

Calculate Deposit_Amount = (0.25*Loan_Amount) + $5,000

shouldn't be:

Calculate Deposit_Amount = (0.25*(Loan_Amount - $50,000)) + $3,750

and similarly for the other ones. That would seem to make more sense to me (at least, that's how income tax is calculated). I mean, the deposit amount should be a continuous function of the loan amount, right? As in, 0 -> 25,000 loan (5% bracket) requires 0 -> 1,250 deposit, 25,000 -> 50,000 loan (10% bracket) requires 1,250 -> 3,750 deposit, and 50,000 -> 100,000 loan (25% bracket) requires 3.750 -> 15,500 deposit. Otherwise, when you go from 24,999 to 25,000 you get a jump of 2,500 in the deposit amount.

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

This is expected. That is exactly why the volatile keyword exists.