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

It's nice to read all the different stories. I find that the common denominator is ".. and I never looked back.".

My field is robotics (mostly mechanical engineering) and so Linux is a very common OS for all sorts of robots and related research activities. I first got introduced to Linux when I did an internship at a German university where they were using Linux for most work, including using a home-brewed simulation library (C++) and most of the programs to control a large Kuka robot (industrial manipulator). I had no experience with Linux and all of a sudden I had to run programs on three different computers (ssh'ing in the terminal) respectively running SUSE and Red-Hat. I would have like it better if I didn't have to do so much without knowing much of the commands and stuff.

Afterwards, I had a few encounters with Linux and QNX, but I was mainly using Windows still (mostly doing engineering work with CAD tools). But then, I did my Master's degree at the Mecca of Linux, i.e. in Helsinki University of Technology (in the computer science department where Linus Torvalds developed Linux). Over there, the only place where you can find a Windows sticker is inside the toilet bowls (I mean, literally, true story, many toilets in the department had Windows stickers inside the bowl or under the seat flap, i.e., where Windows really belongs! Over there, people literally piss on Windows). So, I immediately switched to Linux, installed …

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

Two suggestions:

1) you should make your operator overload a free-function (or friend) not a member function (this can be important for argument-dependent lookup of the correct overload).

2) to chain the operators, you need to return a reference to the printclass object from your operator.

With that, you should have:

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

class printclass
{
  public:
    friend
    printclass& operator<<( printclass& out, const string & mesg );
};


printclass& operator<<( printclass& out, const string & mesg )
{
    cout << mesg;
    return out;
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Because, in the first example, the use of inner2 is only within the definition of the function f() of inner1, while in the second example, the use of the inner2 class is in the declaration of the inner1 class. It is important to understand the difference here. Think of it as a two-pass process. In order for the compiler to build up a complete understanding of what a particular class is, it has to know its entire declaration (i.e. to be able to register what data members it has, what member functions it has, what nested classes / typedefs it has, etc.). But, when you define some functions inside the class declaration, in order for the compiler to know and understand fully the type of the "this" pointer for a member function for example, it has to parse the entire declaration first, and then parse the function definitions, even if they appear in the class declaration. In other words, the compiler looks at all the data members and member function prototypes first, and then comes back to look at the definitions of the member functions. So, in your first example, by the time the compiler looks at the implementation of the f() function, it has already a complete knowledge of the declaration of the inner2 class. With the second example, as the compiler tries to understand the prototype for the constructor of inner1, it finds a class that it has not yet seen, i.e. the inner2 class.

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

If you are interested in such matters, I suggest you read my tutorial on ownership relations between objects in a software architecture.

As a note, I don't like the term "aggregation" (in OOP) because it is fundamentally (in English) a synonym for "composition", both sharing the same definition "The combining of distinct parts or elements to form a whole.".

Also, in that tutorial you refer to, the lack of a clear specification of the ownership of the object is big problem, which leads to the problematic that you are describing. The tutorial just says that the aggregate class doesn't own its subobject, which begs the obvious (and unanswered) question: "who owns it?".

Furthermore, the author leaves a vague open-question at the end that also refers to the problematic you described. He says: "This is generally handled by ensuring other pointers or references to those subobjects exist when the aggregate is destroyed.". Read my tutorial for the answer(s), because that problem is really the central issue, the aggregation "technique" itself is trivial.

Finally, the author's use (and implied recommendation) of raw pointers is also very problematic. Raw pointers are fundamentally ambiguous about ownership, and should thus be rarely used (apart from being encapsulated in the implementation details of a class or data structure).

Now, for your questions:

>> How are you supposed to deal with teachers that are no longer hired?

Teachers should still belong somewhere, or not exist. Either …

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

>>Also, what is Doxygen?

What is doxygen? A documentation generation system that is used extensively in most prevalent programming languages. It is quite awesome actually. Basically, the process is that you put comment blocks in front of each element you wish to document and doxygen will pick them up and generate documentation from them (either as html, latex, rtf, chm, qch, etc.) with full cross-referencing and block-diagrams (inheritance graphs, dependency graphs, call-graphs, etc.).

Here is an example of how it looks in the code:

/// \brief Computes the square.
/**
 * This function will compute the square of a number. 
 * \param X The operand of the square operator.
 * \return The square of X.
 * \author Mikael Persson <mike_2000_17@daniweb>
 * \date Oct. 14, 2011
 */
double sqr(double X);

When all the interesting parts of your code has documentation in the style of the above (and there are more tags too) you can use the doxygen program, configure it the way you want the output to be, the input source-code folders and filters (for files or source code elements), and then you hit "generate" and you have awesome detailed documentation for your code.

Read more about it here. Doxygen is really something that no C++ programmer should ignore. It's a standard tool that everyone uses for generating code documentation. Here are some examples of the output.

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

Before I say anything else, I must point out a few disturbing things.

First, this line:

__glModelReferenceClass__& operator(int index){return __glModelReferenceClass__(win,index);}

Should have been flagged with a compilation warning (if not, increase the warning level to the maximum, as you always should). This function returns a non-const reference to a temporary object. You shouldn't do this, it has undefined behavior, and even if it works, it doesn't mean it's OK to do it. Moreover, there is no need for a reference here, just return it by value (generally proxy-classes should be passed around by value because they are semantically just wrappers for a pointer, a reference, an index-container pair, etc.). Just do this:

__glModelReferenceClass__ operator(int index){return __glModelReferenceClass__(win,index);}

Second, you use the double underscore naming convention quite a lot. I don't know where you picked that up, it is not only illegal (at least for global identifiers as you have there) because names with leading underscores are reserved for the compiler-vendors, but it is also horrible readability-wise. If you want to distinguish your class names from other class names (like glWindow, not interfering other possible glWindow names) then use a namespace, that's what they're for, and you should use a namespace to encompass your code.

Third, when it comes to operator overloading, you should not overload operators in a way that breaks the semantics of the operator. An addition operator is supposed to perform an addition, not an insersion or concatenation or whatever your += operators are doing. …

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

>>Is it possible to put a gap in a class definition?

No. But if you have a use-case we can surely tell you how to solve your problem. There is basically no need to be able to do this, because anything you want to do you can solve it better another way.

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

>>Is the meaning of this "concepts" same as the "concepts" mention in the book "generic programming and the stl"?

Yes. There are a few additional things like concept maps and axioms, but the basic idea of concepts is the same. The STL currently simply documents what concepts the types should model but doesn't enforce them (e.g. most STL algorithms require that the iterator types model one of the iterator concepts (like ForwardIterator or RandomAccessIterator) if they don't, the compiler will still select the function and try to instantiate it, and will fail to do so at the first use of a function or operator that your iterator type doesn't have). The main idea of the proposed "concepts" is to be able to prevent, early, a class or function template from being instantiated if the given type-arguments don't model the required concepts, also selecting function template overloads in the same manner as enable_if (i.e. with Sfinae) based on modeled concepts (which you cannot do currently, you have to use meta-functions like "is_forward_iterator<Iter>" instead of something like "is_valid_concept< ForwardIterator<Iter> >", or you have to use an extra level of indirection like with the tag-dispatching). The Boost.Concept-Check library only allows you to assess of a type models a given concept (with BOOST_CONCEPT_ASSERT) but you cannot do Sfinae or template specializations based on the modeled concepts of the given types. Axioms are an addition and they simply don't exist right now at all, the idea of Axioms is to be able to verify …

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

>>Sooner or later someone will write: const char * pchar=text, where text is an instance of my text_class. Then later, text could independantly be relocated during an insertion of characters, and pchar will points to nowhere and disaster sooner or later.

Well sooner or later that "someone" will have to learn to program correctly and not do such a dumb thing. Do like the standard library does, specify that the char pointer provided by your text_class will not be valid after any subsequent use of the text_class object. Better yet, use the std::string class instead of your own version of it.

>>is there a way to permit only a conversion to a temporary variable

No, not that I know of. If you cannot control the destination type (e.g. it has to be "const char*" and not some proxy class), then you cannot detect whether it is going to be temporary or not, or enforce any requirement for it to be temporary.

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

VC10 supports some of the basic language features such as rvalue-refs. VC11 will add a few insignificant language features, but at least, in VC11, the C++11 standard library will be pretty much complete (put aside the things that cannot be implemented with the limited C++11 language feature support). But almost all interesting features will still be lacking at least until VC12, like variadic templates, template aliases, delegating ctors, inherited ctors, default/delete functions, and initializer lists.

I share your skepticism of MSVC's ability to every reach a reasonable compliance, given their track-record on delivering support for C++98, with about a 10 year delay (since MSVC2008 is about the first decent compiler they produced in that respect). But I think that most features of C++11 should be reasonably easy to add, at least, the GCC team managed to get more of them done pretty quickly, just lacking a few things.

So, I know C++11 is still theoretical for most, but I think it's good to start showing C++11 code (and how it solves some problems pretty neatly) just to build enthusiasm and make the switch as swift as possible (with more pressure on compiler-vendors).

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

I don't see much purpose for it. Stack-based objects are so much nicer to use than heap-allocated objects. I'd be curious to know about your use-case?

The solution is to use a factory function and private constructors, as suggested by firstPerson (and, of course, smart-pointers are strongly preferred to raw-pointers).

If you have C++11 support, there is a very nice idiom to create a factory function, as so:

class MyRational {
  private:
    int num;
    int denom;
    
    MyRational(int aNum = 0, int aDenom = 1) : num(aNum), denom(aDenom) { };
  public:
    //..
    MyRational(const MyRational&) = delete;
    MyRational(MyRational&&) = delete;
    MyRational& operator=(const MyRational&) = delete;
    MyRational& operator=(MyRational&&) = delete;

    template <typename... Args>
    static std::unique_ptr<MyRational>&& Create(Args&&... args) {
      return std::unique_ptr<MyRational>(new MyRational(std::forward<Args>(args)...));
    };
};

int main() {

  std::unique_ptr<MyRational> r1 = MyRational::Create(2);
  std::unique_ptr<MyRational> r2 = MyRational::Create(1,2);

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

>>Link dynamically?

Dynamic linking is the way all GUI tools are used, as far as I know. By default, if you are not modifying the core elements of Qt, and if you are using tools like Qt Creator or qmake, dynamic linking is the way it is done. So, don't worry about that aspect. If you are not using dynamic linking, you will know about because it will most likely involve recompiling Qt, which is not something that will go unnoticed.

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

>>dear mike_2000_17, thanks for your advices

You're welcome.

>>I use boost::remove_extent instead of self define type traits

Great! I didn't know about remove_extent (I don't know everything!). Of course, if something exists already, use it.

>>besides, do c++11 support the enable_if like boost did?

Yes, well sort-of. The C++11 standard does include std::enable_if , like it is documented on msdn (I've actually been pleasantly surprised with the nice C++11 class documentations that msdn have been putting out). And yes, the std::enable_if is essentially equivalent to the boost::enable_if_c (which is OK because C++11 has stricter rules for constant-expressions, which was lacking in C++03 and caused some compatibility problems with some compilers that had a harder time with bool-expressions (like a || !b ) appearing as the bool template argument).

>>I refine my codes, please tell me where should I refine if you think it should be.

It looks pretty good to me. Although I don't like the use of all upper-case (as in TYPE) for anything other than a MACRO or #define. If you want to avoid the somewhat awkward use of the T::value_type and the std::ostream_iterator<TYPE> , if you have C++11 support for range-based for-loops, then you can use this instead:

#include "boost/concept_check.hpp"

template<typename T>
typename boost::enable_if< boost::is_array<T>, void>::type easyCopyImpl(T const &A)
{
  std::cout << "A is an array" << std::endl;
  for(auto x : A) std::cout << x;
  std::cout << std::endl;
}

template<typename T>
typename boost::enable_if< boost::is_class<T>, void>::type easyCopyImpl(T const &A)
{ …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Your problem is with this part (in the array version):

typename std::ostream_iterator<T>(std::cout, "")

First of all, you don't need the first typename keyword because std::ostream_iterator<T> is a type, not a dependent name (doesn't need the typename to resolve it). The main problem, however, is that T is an array type (specifically, int[4] ), which cannot work for the ostream iterator. You need a means to extract the value type of the array, for example, you can do:

template <typename T>
struct value_type_of_array {
  typedef T type;
};

template <typename T, std::size_t Size>
struct value_type_of_array< T[Size] > {
  typedef T type;
};

That will solve that problem.

Also, I generally prefer to put the sfinae switching on the return type as opposed to a default parameter (unless it is a constructor which has no return type). Also, you should prefer to get used to using the enable_if as opposed to the enable_if_c because the former is more portable across compilers (some compilers handle boolean operations in template arguments with some problems). So, your complete and working code can be:

#include <iostream>
#include <typeinfo>
#include <boost/utility.hpp>
#include <boost/mpl/or.hpp>
#include <boost/type_traits.hpp>

template <typename T, std::size_t Size>
std::size_t sizeof_array(const T (&)[Size]) {
  return Size;
};

template <typename T>
struct value_type_of_array {
  typedef T type;
};

template <typename T, std::size_t Size>
struct value_type_of_array< T[Size] > {
  typedef T type;
};

template<typename T>
typename boost::enable_if< 
  boost::is_array<T>,
void >::type easyCopyImpl(T const &A)
{
	std::cout<<"this is array"<<std::endl;
	std::cout<<typeid(T).name()<<std::endl;
	std::copy(A, A + sizeof_array(A), std::ostream_iterator< typename …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Here are a few comments:

int *LargestUsingPointers(const int *array, int n)
{
  const int *p1;
  int *largestIndex; //you create a pointer that points nowhere, because it is uninitialized.
	
  for(p1 = &array[0]; p1 < &array[n]; p1++)
  {
    if(*p1 > array[n])  //you check if the current element is greater than an element that is passed the end of the array and thus, does not exist.
    {
      *largestIndex = *p1;  //you write the value of the current element to a location in memory that is arbitrary and not allocated for this program (and thus, the 'segmentation fault').
    }
  }

  return largestIndex;  //you return a pointer to nowhere.
}

A segmentation fault means that you are attempting to read/write memory that is not assigned to your program, which is what will happen if you dereference a pointer that is not initialized to actually point somewhere.

I think that the intent of your function is to return a pointer that points to the element of the array that is the largest. In which case, this makes more sense:

const int *LargestUsingPointers(const int *array, int n)
{
  const int* largestIndex = &array[0]; //initialize the largestIndex pointer to point to the first element.
  
  for(const int* p1 = &array[1]; p1 < &array[n]; p1++) //iterate through the other elements.
  {
    if(*p1 > *largestIndex) //compare with the current "largest" element.
    {
      largestIndex = p1; //reset the current "largest" element pointer.
    }
  }

  return largestIndex; //return the largest element pointer.
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I believe that the algorithm that you are supposed to arrive to is this:
[TEX]
\pi = 4\sum^\infty_{k=0} \frac{(-1)^k}{2k+1} = \frac{4}{1}-\frac{4}{3}+\frac{4}{5}-\frac{4}{7}+\frac{4}{9}-\cdots
[/TEX]

Ask yourself:

What should be the starting value of pi?

What should be inside the for-loop?

Is the line "pi = 4 * pi" really correct?


Try to compute the above formula with a pen and paper, detailing the steps, and the algorithm to implement will be pretty clear as you see the recurring patterns in the calculation of the different terms.

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

The standard way to do lexical casts is to use the std::stringstream class. Here is an example:

int ToInt(const std::string& s) {
  int result;
  std::stringstream(s) >> result;
  return result;
};

The same will work with just about any type that can input/output with the standard IO streams in C++. See the stringstream class.

For more advanced lexical-casts, you can use the Boost.Lexical-cast library.

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

>>I just think VLA should be implemented for backward compatibility with C code.

I think that the standard committee has been less and less preoccupied with backward compatibility with C. I think the C support rational can be summarized as: "if new C++ features can be realized without breaking C features, they will, but if C features have to be broken (or left unsupported) in order to implement 'superior' C++ features, they will be broken". The introduction of the "class" keyword instead of "struct" (which are essentially similar in C++) to not interfere with the definition of "struct" in C is a good example of the former, while the "auto" keyword in C++11 is a good example of the latter.

I know that some people like to think that C++ should be strive to be a super-set of C. It was the main opinion in the 80s. Now, there isn't as much motivation to do so, because very few people still see C++ as a super-set of C, and if anything, they see the backward compatibility for C provided by C++ as a low priority. Since C is also moving further away from C++ in its own way (VLAs, built-in complex numbers, and upcoming C1x features), I think it is time for you and many others to accept the divorce of C and C++.


>>It will be used only by complete beginners, and C code

I would teach beginners to use std::vector (and I …

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

Scott Meyers started a huge discussion on usenet about this topic, pretty much all the arguments you can think of there find you will.

The gist of the argumentation is that there are too few use-cases and the changes required to implement them in C++ are pretty big and deep. Basically, people argue that: 1) if you don't have a reasonable upper-bound for the size of the VLA, then you should use a dynamic array (on heap) or an STL container (like std::vector); 2) if you have a reasonable upper-bound, then you could simply use a static array with that upper-bound size and simply use a subset of it (e.g. have an STL-like container whose storage is a static array of fixed maximum size). And thus, the compelling use-cases are few and far between.

Then, you have to consider that even though C and C++ share many similarities, the type system is fundamentally different. C++ enforces stricter rules on types (i.e. it is more strongly typed than C). C++ also has a lot more compile-time mechanism, like sizeof , decltype , alignof , etc., whose behaviour would be deeply affected by the presence of one type whose true identity and size are not known at compile-time (currently, in C++, all types are resolved at compile-time, and many features depend on that). I'm not a good enough expert to really know all the changes that VLAs would trigger, but I know they would be significant and far …

sergent commented: . +7
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The "Lesser" General Public License means that you can use the library for any application (commercial or not, open-source or not) as long as all you do is link against the library's binaries (i.e. if you don't use the source files (only headers) and you don't modify components of the library or add new ones). So, yes, you can just use Qt under the LGPL license, no need for the commercial license. You would need to purchase the commercial license if you wished to add or modify the Qt library components themselves (and thus, recompile and redistribute the Qt binaries (.dll or .so files)), but not if you just use them.

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

Here are a few comments:

By convention, the type for all array sizes (and return value of sizeof()) is the standard size type, which is std::size_t . So, you should probably have:

template < typename T, std::size_t elements >

Your data member that you call "ptr" is a static array, not a pointer (as its name implies). It is important to understand that.

Since you are writing what is essentially a header file, you should NOT have an using namespace std; statement. This is an important guideline and you should learn to obey it sooner rather than later.

Personally, I don't like the use of the bare class template name within the class declaration (and worse, in the definition, if the compiler allows it). What I mean is this in the class declaration:

template<typename T,int elements>
class Array
{
 // ..
   const Array &operator=( const Array & );  //I don't like to see this.
  
   const Array<T,elements>& operator=( const Array<T,elements>& ); // I prefer this.

   //or, even better, this:
   typedef Array<T,elements> self;
   const self& operator=( const self& );

 // ..

When you move outside the class declaration (to write your member function definitions) you should always use the fully specialized name Array<T,elements> instead of the bare template name Array . That probably explains your problem with the assignment operator.

Now, for your first question about the iostream operators. This is a bit of mind-bending problem, that is, if you wish to understand the problem, as …

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

The basic requirement for the default assignment operator to be available for a class is that all the data members and base classes also have an assignment operator available (with the additional exception that data members of reference type also disable the default assignment operator because of the special semantics they have).

So, you can consider, for practical purposes, that the default assignment operator has the following implementation generated by the compiler:

class A : public B, public C {
  private:
    int x;
    double y;
    some_class z;
  public:

    //The default assignment operator would look like this:
    A& operator=(const A& rhs) {
      //first, assign base-classes:
      B::operator=(rhs);
      C::operator=(rhs);
      // then, assign the data members:
      x = rhs.x;
      y = rhs.y;
      z = rhs.z;
    };
};

Clearly, the above can only work if all the data members can be assigned a value, and if all base-classes have an assignment operator (default or not).

In your example code, the class A has a const data member which cannot be assigned a value (it is "constant") after initialization (in the initialization list of the constructor). So, the class A does not have a default assignment operator generated for it, and in turn, the class CMyClass will not have a default assignment operator generated for it either since it has a data member which is not assignable (m_A).

Jsplinter commented: Thorough. I see now. Thank you. +3
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>What did it mean before it was used for a variable? auto is a storage specifier in C (and kept in C++98). However, it is the default storage class for all variables in C/C++, which makes it a pretty meaningless specifier (i.e. it literally has no effect at all). A storage specifier is used to tell the compiler how long a variable should exist and where it should be stored or found.

Personally, I have never seen auto used anywhere (after 13 years or so), I had to look it up to answer your question because I wasn't even aware it was a storage class in C++ (I thought that only static , mutable and extern existed, which are the only ones that actually matter). Now, that I know about it, I am not surprised that I had never seen it before because it is clearly useless, i.e., it changes absolutely nothing.

In the C++98 standard, the storage specifiers auto and register are allowed because they exist in C and were kept for backward compatibility, however, they were essentially meaningless in C++98. The register specifier has a theoretical but small effect, but it will be ignored by almost all modern compilers (it's basically a hint to help the compiler to optimize code, but modern compilers don't need such a hint anymore). Today, the new standard (C++11) still allows the register specifier, but the allowance for the auto keyword to appear as a storage specifier was removed (e.g. a …

Zssffssz commented: Did more than expected (in a good way) +3
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

My guess is that you enabled back-face culling (or didn't disable it).

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

You are a bit confused with the standard numbering. What you seem to refer to as C++09 is actually not C++09. The newest standard which just came out this summer is called C++11 (as in, 2011). But, it has been in the making for quite some time (since the last standard revision, C++03), and during that time it was referred to as C++0x (as in, it was supposed to come out in year 200x, but the delays and deliberations lasted longer and it only came out in 2011). So, if you are looking for information on the auto keyword, look for them on pages about either C++11 or C++0x, the wiki page is a good start.

Basically, the auto keyword allows you to create a variable whose type will be deduced by the compiler based on what it is initialized with:

auto some_variable = 5;  //the compiler will deduce the type as 'int'.
auto other_variable = 5.0;  //the compiler will deduce the type as 'double'.
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Code please? We can't really help much without seeing your attempt at it.

N.B.: I hope you are aware that in C/C++ you cannot write a file-path as "C:\Program Files\my\path\file.txt", because the slash "\" character is an escape character. To actually get the "\" character, you need to write "\\" instead, as so: "C:\\Program Files\\my\\path\\file.txt".

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

First, some corrections on Fbody's comments:

>>The second version is called an "implicit" declaration

No. To be accurate, (8.5/14) a syntax like int a = 42; is called a copy-initialization, and will be realized with an implicit type conversion if one exists (either as an implicit converting-constructor in the destination type or an implicit conversion operator in the source type). Moreover, (8.5/15) a syntax like int a(42); is called a direct-initialization and will be realized with a constructor of the destination type (explicit or not) and possibly needing an implicit conversion of the source type (e.g. int to double). (5.4/2) A syntax like int(42); is an explicit type conversion by means of a functional notation (as opposed to the type conversion operator (like static_cast<int>(42); ) or a cast expression (int)42; ).

>>Except for a single-argument constructor, which can be either explicit or implicit depending on whether or not the explicit keyword was used, they are explicit.

They are not explicit, because the implicit/explicit concept only applies to type conversion methods. It is only meaningful to talk about a constructor being explicit or not when you talk about a converting-constructor (12.3.1/1), all other constructors are neither implicit nor explicit, they are just not converting-constructors.

Also, to further drive home the point that implicit/explicit applies only to type conversion methods, the new standard now allows you to specify conversion operators to be explicit as well (12.3.2/2). So, implicit/explicit only applies to means of type conversions, not to …

Fbody commented: :( I'm getting really tired of you spouting Doctoral dissertations at me. -3
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Exporting a class is something that is pretty hard to do correctly. I don't recommend you try it. In general, I have not seen anyone do it on Windows (in *nix systems it's a different story). Generally, the idea is to export a factory function (and the corresponding destroying function) to handle the create/destroy of the object, and then make all member functions 'virtual' such that you get all the member functions exported for free. But, even when doing that, you still need to worry about a lot of ABI issues (ABI: Application Binary Interface). This is not an easy task (it literally took me 3 years to figure it out for my own purposes, as a little side project, of course).

Read this article, it's a pretty good start to understanding the issues involved.

The easiest solution, really, is to use only a C-style interface for your DLL. With that, your code could look like this:

In the test.h for both the DLL and the application:

#ifdef WIN32
  #ifdef COMPILING_THE_LIBRARY
    #define DLLFUNCTION __declspec(dllexport) __stdcall
  #else
    #define DLLFUNCTION __declspec(dllimport) __stdcall
  #endif
#else  //for *nix systems (no need for anything special)
  #define DLLFUNCTION
#endif

class test; //forward-declaration.

extern "C" {

test* DLLFUNCTION CreateTest(int aA);

void DLLFUNCTION DestroyTest(test* t);

int DLLFUNCTION TestNum(Test* t);

};

In the test.cpp for the DLL:

#include "test.h"

class test
{
  private:
    int a;
  public:
    test(int a);
    int num();
};

test::test(int aA) : a(aA) { }

int test::num()
{
  return a; …
Stefano Mtangoo commented: this is good one! +13
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>But in this example I would need to be unable to make an anotherclass from outside of myclass. Is this possible and if so what is the syntax for it?

Well, the code that you showed, or that of L7Sqr, achieve exactly that. Another way is to create a separate class (not nested), make all its members private (including the constructors/destructor) and then make friendships to the selected few classes that should use that hidden class.

There are also other alternatives to "hide" a class. Often, you don't implement a complex class as just one class, it is often useful to break it up into helper classes. Now, since those helper classes are part of the "implementation details" of the containing class, you often want to hide them away from the user of your library. There are two very common practices to do so:

1) If you want your helper class to be hidden from the user but available for developing other classes in your library, then people often will use a "detail" namespace. By convention, anything that you find in the "detail" namespace of a library are things that you should not use unless you are developing things in that library. Here is how you generally do it:

// in "detail/my_helper.h":
#ifndef MYLIB_DETAIL_MY_HELPER_H
#define MYLIB_DETAIL_MY_HELPER_H

namespace my_library {  namespace detail {

class my_helper { 
  //...
};

}; };

#endif

//in "my_class.h":
#ifndef MYLIB_MY_CLASS_H
#define MYLIB_MY_CLASS_H

#include "detail/my_helper.h"

namespace my_library {

class my_class {
  private:
    detail::my_helper …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>I don't fully understand why, it's something about the way templates work "under the hood", it's just one of those things you have to do.

This is a fundamental aspect of templates, and it is important to understand it:

A function or class template is NOT a function or class, it is a set of instructions (template) for the compiler that tells it how to _generate_ an actual function or class once the template arguments (like T) are specified (e.g. at the point where Queue<int> is used, this point is called the "instantiation").

Once you understand that, then it becomes clear that the _compiler_ (not linker) has to see the implementation (definition) of the function / class templates in order to be able to generate the actual code upon instantiation. So, you cannot put the definition of function templates in a separately compiled cpp file. The options are to either:

1) define the function templates at their declaration-site (in header);
2) define the function templates anywhere in the header file;
3) define the function templates in a cpp file which you #include at the end of the header-file (within the guard);
4) define the function templates in a cpp file which has a set of explicit template instantiations for all the possible or useful instantiations of those function / class templates.

This was the main point in the earlier link given by vijayan121.

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

>>what is the meaning of (&)?

It means that the parameter type is "a reference to a static array", as opposed to just a static array in the first case.

>>Why version one fail?

That's difficult to say. I was aware of this particular problem (it is well known), but it's not super clear why the first version fails. I believe the problem occurs as the compiler tries to find the matching type argument (T), and in that process of converting the parameter to an rvalue (to be passed by value) it figures that the static array should be converted to a pointer (to the first element) and once that is done, it deduces T to be a pointer (say int*) which leads to the parameter not being an array any longer (as it is now just a pointer), that causes the template-argument substitution to fail, and thus eliminating that function template from the set of overload candidates. Essentially, it is a quirky result of this ambiguity in C/C++ between arrays and pointers (because arrays are implicitly converted to pointers). Anyhow, making the parameter a reference rules out the conversion of the array to a pointer, leading to a successful argument deduction of the size value.

As I understand it, in the standard, the array-to-pointer conversion is considered the Lvalue Transformation operation to do on an array. So, the compiler deduces that the function template needs an rvalue, which triggers the conversion of the …

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

>> So in the end, there isn't any C++ features for what I want?

That I know of, there is no specific C++ language feature to allow this.

>> Are you aware of any discussions for future enhancement (such as the "scoped friends" suggestion above)?

I doubt it. The friendship relation is a very frowned upon feature. The expert rarely use it much (I know I don't), and generally say that requiring a friendship relation is an indication of poor design (I know I do). Generally, for standard committee efforts at improving the language, they rarely discuss of ways to make it easier to do the wrong thing, but rather concentrate on easier ways to do the right thing (for examples: rvalue-refs, explicit defaulting/deleting member functions, or the, now abandoned but really awesome, feature of "Concepts").

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

>> i would love to do system programming or game programming.

System programming: Learn C and get some basics in assembly.

Game programming: Learn C++. The computer game industry is entirely dominated by C++ (and it is probably good to know C and assembly as well).

>> i dont like web programming

Then, why bother with .NET?

>> should i stick to visual c++?

Stick with C++, period. This is a language worth mastering, regardless of what you actually want to end up doing (as long as it is still programming-related).

>> or start with mfc?

MFC is old and being deprecated. You can still learn it and use it, and it will probably be backwardly supported for at least a decade still. But there is no need to learn it at this point. The thing with GUI tools (like MFC, VCL, Qt, WinForms, etc.) is that they are all pretty similar, and using one or the other is as hard as driving a different car from time-to-time (i.e. you just have to adjust the seat, get used to the clutch and stick, locate the buttons and the wiper thingy, and you're good to go). Personally, I worked a lot with VCL (Delphi) in the past, when I started to use Qt instead, the time it took me to get comfortable using Qt was about one hour. So, to learn to do GUI programming, it doesn't matter much which tool you learn, …

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

For the more general problem, if you really have sub-parts of your class that are distinguishable enough that you would need different friendship relations for them, then these sub-parts should probably be implemented as separate classes and composition should be used to create the overall class at the end. In other words, try to avoid monolithic classes.

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

Say you are writing a vector class.
1) You want to provide public access to checked element access function (checking that element index is withing bounds). All is great.
2) You may also want to provide access to unchecked element access function (with crash risk) to very few and selected other functions. You use "friend". Life is good.
3) You don't want nobody to mess with the internal of your vector: but because you gave friend access in (2) to some function those functions could do that! Life is hard.

Here is a solution for that problem:

class my_vector {
  private:
    std::vector<int> v;
  public:
    my_vector() : v(5) { };

    // Safe index operators:
    unsigned int size() const { return v.size(); };
    int& operator[](int i) { return v.at(i); };
    int operator[](int i) const { return v.at(i); };

    // Unsafe index operators inside a nested class:
    struct unchecked_access {
      my_vector& parent;
      explicit unchecked_access(my_vector& aParent) : parent(aParent) { };
      unsigned int size() const { return parent.size(); };
      int& operator[](int i) { return parent.v[i]; };
      int operator[](int i) const { return parent.v[i]; };
    };
    struct unchecked_const_access {
      const my_vector& parent;
      explicit unchecked_const_access(const my_vector& aParent) : parent(aParent) { };
      unsigned int size() const { return parent.size(); };
      int operator[](int i) const { return parent.v[i]; };
    };
};

int main() {
  my_vector v;

  v[0] = 42; //uses checked access.
  my_vector::unchecked_access(v)[0] = 69; //uses unchecked access.

  return 0;
};

A nested class has access to all the members, so, a typical means to …

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

You just have to add this after your declaration of the CWindow class:

std::map< HWND, CWindow* > CWindow::m_hWnd_CWnd_map;

I just forgot to put that in the code I posted.

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

>>The program runs perfectly

Your program is going to run correctly. The thing about using the "this" pointer in the initialization list is not a matter that the this pointer's value (the address of the object) is not correct, it is correct. The problem is that, at that exact point in time, the this pointer points to an incomplete object (meaning some data members have not yet been initialized). So, the danger is that if the this pointer is used (dereferenced to access a data or function member) then that operation could be dangerous and execute erroneously. But, if all you do is store that pointer (in a data member of the base class or by passing it over to a windows API function as the "userdata" pointer) and guarantee that it will not actually be used until all the constructors have finished (derived and base), then your program will execute just fine and is well-formed. So, in your code, since you only call the Run() function once the CFrame object has been created, your program will and should run correctly.

>>In Code::Blocks 10.05 using MinGW I get no warnings and a perfectly clean compile.

This is probably because of a warning-level issue, but I do not remember if GCC will give such a warning, this is a bit of a fringe case.

>>If there is a problem I'd like to know about it.

There is no technical correctness problem, i.e., your program does and …

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

>>Believe it or not, there are programs out there that cost thousands of dollars and all they do is analyze beams.

Yes I know, and I've used them (PATRAN/NASTRAN, ANSYS, etc.). But lately I've been using one that is free and fairly feature-rich (thermo-mech, dynamic, multi-physics, etc.). This tool is called Code-Aster (for FEA) and Salomé (for the GUI). This is an open-source project with many university research partners and some industrial partners. I highly recommend that you use that as a basis for your project.


>>so let me explain a bit (in case you are not familiar with it) I am sorry but I think I have to explain it to you so you can help me.

I am quite familiar with the type of software you are describing. I'm not an expert in it (my field is more about multi-body dynamics simulation) but I do have a very good idea of what it entails (and I have studied, written and used finite-elements software before).


>>A simple programs would have several tabs, one for project information, another to indicate the beam information (basically a thick line) here you indicate how many spans and the type of support (fixed, pinned, etc…) another tab for the loading (you have to specify the coordinates, just the x and y cause 2d) and one to calculate and show results.

What you are describing is a GUI (Graphical User Interface) for a FEA / structural …

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

I also agree with the rest of the posters that this project is pretty huge, you are basically detailing the entire construction of a library for finite-element analysis (and related code).

C++ is certainly a suitable language, and you can probably fairly easily translate your excel code into C++ code if you use a library for efficient matrix algebra (for example, Eigen, uBlas, or MTL).

Have you considered reviewing the Code.Aster project. This is an open-source finite element software suite. If you have special methods to implement beyond the simple FEM algorithms (generating meshes and solving linear sparse systems), then I would suggest that you take a look at that project and see if you cannot just add your methods or codes to that library (the developers of Code.Aster would probably help you get started).

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

I think that the instructions on the boost website are already pretty much "step by step", I don't know how I could give any more straight-forward instructions.

Also note that most Boost libraries are header-only libraries, meaning that you don't actually need to build the binary libraries to use those header-only libraries.

>>my compiler does have minimal support for C++0x, will boost work on it(MSVC 2010 express).

Yes, Boost uses the old standard C++03, so you don't have to worry about that. Boost is also made to compile properly on pretty much any compiler (even very old sub-standard ones).

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

>>how can I sleep my program without sleeping others (or making them slower)?

You can't make other programs sleep... What are you talking about, what are "the others". The Sleep function is perfectly ok, it "Suspends the execution of the current thread until the time-out interval elapses." - msdn. What else do you want? If your other threads are seem to go to sleep, then it's a problem with those threads, not with the use of Sleep().

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

>>I can't for the life of me figure out a way to copy the value stored in the char array into a bigint and I don't think the developers of the bigint libraries intended for them to be used that way.

The developer of bigint did indeed provide a function for input/output with standard streams (istream ostream) and you can easily use that to turn a char-array into a bigint and vice versa, using the std::stringstream class. See the BigIntegerUtils.hh file.

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

This piece of code makes no sense:

struct NArcher {
  extern int enemyattack = 10;
  extern int enemyhealth = 20;
  extern int enemydefense = 5;
  extern char enemy = 'Nathan Archer';
} ;

First with the obvious, if "enemy" is supposed to store a string, it should be a string, not a char. You can either have char* enemy = "Nathan Archer"; or std::string enemy = "Nathan Archer"; (notice the double quotes for defining a string, the single quote is only for defining a single character).

Now for the more important problem, i.e., your use of the extern keyword. First, you have to understand the fundamental difference between a data member, a static data member and a global variable. A data member, like "foo" in:

struct myClass {
  int foo;
};

is a variable that is within an object of the class (myClass). This means that when you create an object of that class, e.g. myClass myObj; , you can access the data member inside the object with myObj.foo . This means that you have one such data member inside each object (each with its own value).

A static data member, as "bar" in:

struct myClass2 {
  static int bar;
};

is essentially a global variable that is associated to the class it is declared in. This means that there is one such variable in the whole program, regardless of how many objects of that class you have (or none). So, since a static data …

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

You forgot the "extern "C"" part. This is important because the C++ compiler mangles the names of functions (to be able to attach to the function name certain information required in C++, such as the types and number of the parameters the function takes). In C, there is no need for that (function's in C are not type-safe nor overloadable). So, when you ask to get the address of the function named "PluginEntry", the loader will not find it because the C++ compiler that generated your DLL will actually have changed that name to something else (e.g. "__XFS34W!PluginEntry34ZX@24!" or something resembling that). So, in order to tell the C++ compiler not to mangle the name of the function (and use "C" rules for external symbols), you add:

#include <windows.h>

extern "C" __declspec(dllexport) void __stdcall PluginEntry()
{
	MessageBoxA(0, "Plugin entry point!", "", 0);
}

Also, make sure that your PluginEntry function-pointer type is declared with the same calling-convention (stdcall) as:

typedef void __stdcall (*PluginEntry)();
jammmie999 commented: Thanks for professional, accurate, quick and easy to understand feedback! +1
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

A few things to check:

1) Verify that your library is correctly loaded, i.e. Test != NULL 2) Verify that your function pointer is correctly obtained, i.e. Entry != NULL 3) Make sure that the "PluginEntry" function (in your DLL) is declared with extern "C" 4) Verify that your calling conventions match for both the declaration of the "PluginEntry" function (in your DLL) and for the function pointer type PluginEntry.

Post your code for the DLL function and the definition of the function pointer type PluginEntry if you are unsure how to test the last two points above, we can tell you if it is correct or not.

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

Definitely GCC is the best (and only) compiler right now that has a pretty good support for C++0x (C++11) features. A quick look at this table reveals this pretty clearly. And specifically for GCC here. From looking at the list, you can see that 4.6 is a pretty good version, the things added by the absolute newest version (4.7) are not that important (and, of course, 4.7 is not released yet, but under development, so it can be hard to get it working on Windows). As suggested, you can use the nuwen build of MinGW for the state-of-the-art releases of GCC for windows. Using Cygwin is also an option I guess.

As for MSVC, don't even think about any version before 2010. Also note that, unlike GCC, MSVC enables C++0x features by default (in GCC you have to use the option -std=c++0x , or -std=gnu++0x for the GNU dialect). I wouldn't put too much hope in MSVC for standard compliance (considering the MSVC 2008 is the first decent version with respect to the C++98 standard), although this post is encouraging.

Another important consideration is the standard library support. On GCC, it is pretty close to complete (except for the things that rely on unsupported language features, and other the notable unsupported libraries are Regex and Future). As for MSVC10, I don't think they have done much more than promoting the TR1 libraries. However, good news! MSVC11 will feature an almost …

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

>>Well... why would you want to enter "a"?

That's called "fool-proofing a program". Generally, when writing a program that deals with a user (either through console input, command-line input, config-file input, or a GUI), you must assume that the user has an IQ of 0, i.e., that he/she is an absolute imbecile that could be inputting anything and click on all or any buttons. That's often what beta-testing is about, have a user do all sorts of random crap and watch if the program can cope with it.

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

>>it saves a set of CollisionCheck unions that can be spheres, or planes, then checks each one

Definitely, this is the way to go. Doing collision checks between simple 3D shapes is a method that is accessible to a novice programmer and it is often sufficient for many purposes.

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

You could use setw and setfill functions to avoid that if-statement in your loop. As so:

#include <iostream>
#include <iomanip>
#include <windows.h>
#include <cstdlib>

using namespace std;
int main(){
    int minutes;
    int seconds;
    cin >> minutes >> seconds;
    seconds = (minutes*60)+seconds;
    cout << setfill('0') << endl;
    while(seconds>0){
        cout << seconds / 60 << ":" << setw(2) << seconds % 60 << endl;
        Sleep(1000);
        seconds--;
    }
}
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>I thought of stepping through the vector from start to end in small increments, but that would be slow and might pass right through the polygon sans interference. Any hints?

I'll just to add a concrete hint for that particular problem. Try a method like this (a secant-like method):

1) Find the vertex of your mesh that is the closest to the starting point of your line segment.
2) Compute the vector that goes from the start-point to the closest-point from the mesh.
3) Project that vector on the line-segment and that will give you a new point on the line.
4) Repeat the steps (back to 1)) with the new point instead of the start-point.

It will not be as simple as the above, but it's a good start. I believe that if you do the same procedure by starting at the end-point of the line-segment, you should be able to finish both algorithms and get points on the line-segment that should tell you if there is a collision or not. Also, using the normal vectors associated with the vertices of your mesh is an important information to determine if a collision actually occurs.

But more formally, this problem is easily solved with a Simplex Method.