vijayan121 1,152 Posting Virtuoso

isnan() is from C99; and is not part of C++98. See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.15
In C++0x, isnan() is part of TR1.

You could easily roll out isnan() and isinf() on your own, though:

#include <limits>

template< typename T > inline bool isnan( T value )
{ return value != value ; }

template< typename T > inline bool isinf( T value )
{
    return std::numeric_limits<T>::has_infinity &&
           value == std::numeric_limits<T>::infinity() ;
}
vijayan121 1,152 Posting Virtuoso

> What does initializing the run-time stack entail? Does this process define the stack pointer?
> Shouldn't that information already be "known" and readied within __start?
> For instance loading the stack pointer into register 29 (MIPS)?

On MIPS, that could be the case, with _start being passed all information via registers.

> My ELF file has the following headers(I assume that somewhere along the way I have enabled debugging which has generated several additional segments):

most of the additional sections are because of debug information, a few others like

.reginfo          MIPS_REGINFO

are MIPS specific. Presumably, this contains the information about MIPS register usage by the program.

> Do you know why my __start section looks so different (__start shown below)?
> Also, why do the virtual addresses shown in gdb jump around and increment by 2 sometimes, larger numbers other times.
> Shouldn't the instruction interval always be 4 bytes? (32bit)

The output produced by gdb you have used is garbage; it is trying to interpret the MIPS binary, thinking that it is an Intel binary. You need to use a gdb built for MIPS executables.

> Also, this is the objdump of __start using objdump. This doesn't resemble what I assumed was __start using gdb

The objdump output is the correct one; this would have been produced by the objdump built as part of binutils during the cross-compiler build.

> From what I can tell …

vijayan121 1,152 Posting Virtuoso

> does the loading sequence for an ELF file start (from the absolute beginning of the loading process) at the _start tag in .text?

The loading sequence starts with a syscall to execve with the file name and comandline as args. execve reads the file, examines the elf headers, loads program sections into the virtual adress space, initializes the runtime stack and then passes control to the entry point specified in the elf header.

The following is for Unix (FreeBSD/i386); I suspect Linux could be somewhat different from Unix. If you have access to the target MIPS machine, copy the program to that and then check it out yourself - that is always the best way.

>ktrace ./hello && kdump
hello world
 51605 ktrace   RET   ktrace 0
 51605 ktrace   CALL  execve(0xbfbfe85b,0xbfbfe6b0,0xbfbfe6b8)
 51605 ktrace   NAMI  "./hello"
 51605 hello    RET   execve 0
 51605 hello    CALL  fstat(0x1,0xbfbfe514)
 ...

The entry point is _start, so yes, the program begins executing at the _start tag in .text

> an instruction near the beginning of _start loads deadbeef into the program
> which denotes that some previous instructions should have placed a real value where the deadbeef was.

Verify that there is no dynamic segment in your executable.
A standalone executable (all of the following are only for executables without a dynamic segment in them) should look something like this:

>readelf -d hello
There is no dynamic segment in this file.

>readelf -S hello
There are 14 section …
vijayan121 1,152 Posting Virtuoso

> I asserted the flag -static-libgcc on compilation of my hello.cpp file (hello world program).
> Apparently this is not enough though. Because there is still a segment in my executable which contains the name/path of the dynamic loader.
> What flags do I use to generate an executable which contains EVERYTHING needed to be run?

The flag to use is -static to link everything statically or -static-libgcc to just link to libgcc statically.

For example, with this hello.c

#include <stdio.h>

int main()
{
    puts( "hello world" ) ;
    return 0 ;
}

This would link to the shared libraries:
gcc -Wall -std=c89 -pedantic -Werror hello.c -o hello && ldd hello
libc.so.7 => /lib/libc.so.7 (0x2808e000)

And this should create a standalone executable:
>gcc -Wall -std=c89 -pedantic -Werror -static hello.c -o hello && ldd hello
ldd: hello: not a dynamic ELF executable

Executable files need some code that initially sets up the process environment for an executable, initializes the C and C++ libraries, in C++, perform dynamic initialization of statics (eg. invoke constructors of global objects); all that needs to be done before entering main(). Then this code calls main, and when main returns does the deinitialization and returns to the kernel via the exit syscall. The actual code is obviously highly platform specific.

In elf executables generated by the gnu toolchain, to set the entry point of the executable, the linker looks for a symbol named _start. This symbol is …

Agni commented: Always learn something from your posts :) +3
vijayan121 1,152 Posting Virtuoso

> as far as i understand the if statment should stop evaluating if the first condition is false
> [as it is an && operation] (ie no player occupies the seat, therefore the pointer is invalid)
> so it should not try to evaluate the player->inRound bit

Your understanding is correct.So it will it be completely safe if isOccupied is set and cleared correctly.

> secondly if this is bad code can you suggest a safer way to do such a thing?

It is not bad code unless it sets isOccupied incorrectly. The only extra safety that can be provided is
a. Make sure that seat[x].player is set to zero whenever the seat is not occupied
b. Provide an extra check to verify that seat[x].player is not a null pointer before you try to access seat[x].player->inRound

vijayan121 1,152 Posting Virtuoso

Use std::getline to read line by line.
Use a std::istringstream to extract the words in the line.

while( std::getline( file, line ) ) // read line by line
{
    if( line == "" ) // just a '\n' in file
    {
        // an empty line, new paragrah logic
    }
    else // split the line into words
    {
        std::istringstream stm(line) ;
        std::string word ;
        int chars_in_line = 0 ;
        enum { MAX_LINE_LENGTH = 80 } ;
        while( stm >> word ) // read word by word
        {
            if( ( chars_in_line + word.size() ) < MAX_LINE_LENGTH )
            {
                // print the word, and then a space
                // add word.size() + 1 to chars_in_line
            }
            else if( ( chars_in_line + word.size() ) == MAX_LINE_LENGTH )
            {
                // the word just fits on the line
                // print the word, and then a newline
                // reset chars_in_line to zero
            }
            else
            {
                // the word doesn't fit on the current line
                // print a newline, then the word, then a space
                // reset chars_in_line to word.size() + 1
            }
        }
    }
}
vijayan121 1,152 Posting Virtuoso

Open the stderr log file for writing (with CreateFile ).
Call SetStdHandle( STD_ERROR_HANDLE, log_file_handle ) ; to redirect stderr for the process to the log file.

vijayan121 1,152 Posting Virtuoso

Use std::vector<bool> for space efficiency (if N is large).
And std::transform and std::count for programmer efficiency.

#include <iostream>
#include <vector>
#include <functional>

int main()
{
    const bool TAIL = false, HEAD = true ;
    enum { FLIP_THEM = 0, COUNT_HEADS = 1 } ;

    std::vector<bool>::size_type N, Q ;
    std::cin >> N >> Q ;

    std::vector<bool> coins( N, TAIL ) ;
    std::vector<bool>::iterator begin = coins.begin() ;

    int command ;
    std::vector<int>::size_type pos_from, pos_upto ;

    while( ( Q-- > 0 ) && ( std::cin >> command >> pos_from >> pos_upto ) )
    {
        if( command == FLIP_THEM )
           std::transform( begin+pos_from, begin+pos_upto+1,
                           begin+pos_from, std::logical_not<bool>() ) ;

        else if( command == COUNT_HEADS )
           std::cout << std::count( begin+pos_from, begin+pos_upto+1,
                                    HEAD ) << '\n' ;
    }
}
vijayan121 1,152 Posting Virtuoso

> Why does C++ seem more complicated than Visual Basic?

Because it *is* more complicated than Visual Basic.

But you don't need to be extraordinarily brilliant to learn C++ and to use C++ effectively. Almost all programmers who make a genuine attempt to become good C++ programmers do succeed in their attempts. In a reasonable period of time, which is more than what is required for, say, Visual Basic. The world is complex, some problems are hard, and the tools we use to solve those difficult problems are necessarily more complex.

vijayan121 1,152 Posting Virtuoso

> I have the number of paragraphs and now I want to store the number of lines in each paragraph in a vector.

You do not need to calculate these separately - once you have the number of lines in each paragraph in a vector, the size() of the vector would give you the number of paragraphs.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

int main()
{
    std::ifstream file( "whatever.txt" ) ;
    std::string line ;
    std::vector<int> lines_in_paras ;
    int lines_this_para = 0 ;

    while( std::getline( file, line ) )
    {
        if( line == "" )
        {
            if( lines_this_para > 0 )
            {
                lines_in_paras.push_back( lines_this_para ) ;
                lines_this_para = 0 ;
            }
        }
        else ++lines_this_para ;
    }

    if( lines_this_para > 0 ) // for the last paragraph in file
          lines_in_paras.push_back( lines_this_para ) ;

    std::cout << "#paragraphs: " << lines_in_paras.size() << '\n' ;
}
vijayan121 1,152 Posting Virtuoso

Write a constructor for A

class A
{
   public:
      A( /* ... */ ) : fv( length, fix_fac ) {}
   private:
     fixvec fv ;
};
vijayan121 1,152 Posting Virtuoso

> When you say to run the program on an ARCH2 or 3 processor what exactly do you mean?

Run on any 32-bit MIPS processor other than the original R2000 and R3000 processors.


> I very specifically need to run on the MIPSI ISA and more importantly
> I need some sort of control over what ISA I'm compiling in.
> Do you mean set the march flag to the MIPSI processors like R2k or R3k?

You have already set the march flag to MIPSI ISA for the files that you are compiling by specifying -mips1. The elf flag is MIPS ARCH2 because some of the libraries that you are linking with have been compiled for MIPS ARCH2 ISA.

Since you are not linking to shared libraries (by specifying -non_shared), fixing this is easy. In a separate directory, stage builds of the libraries that you are using (just libc and libstdc++ as far as I can make out) with the -mips1 flag. And then link to these staged libraries statically. The elf e_flag for the executable will then be mips1 and you can run the program on any 32-bit mips processor.

vijayan121 1,152 Posting Virtuoso

For MIPS, each ELF object module keeps track of its own OMF flags. The linker copies the appropriate flags from the original object module; if two different files have different sets of flags, unless they are conflicting flags, the more restrictive one is applied and a dignostic is generated: "xxx.o uses different e_flags (0xyyy) than previous modules (0xzzz)"


The extra flag present is EF_MIPS_NOREORDER. This flag was set because somewhere in the code for an object file, a .noreorder directive was given. The assembler is free to reorder instructions to avoid pipeline delays; .noreorder disables this. There would not be any problems related to this flag differing between your original object modules and the final module.

The flag that is differing is E_MIPS_ARCH_2 (mips2). The executable was linked with at least one module compiled for the mips2 architecture. Because of this, you need to run the program on an ARCH2 or ARCH3 processor, and it would run fine.

The -mno-abicalls (do not generate PIC) and -non_shared (link against static libraries) only affects how the code is generated and what object modules are linked in; they would not appear in the elf header.

vijayan121 1,152 Posting Virtuoso

> My operator+= works
> However i cant get the operator+ to work

The problem seems to be in your copy constructor; operator+ needs to make a copy.

First, verify that the copy constructor Str2::Str2( const Str2& ) is working correctly.

vijayan121 1,152 Posting Virtuoso

> warning C4293: '<<' : shift count negative or too big, undefined behavior

56, 48, 40 are greater than the number of bits in an int on the implementation you are using (which seems to have a 32 bit int). Convert (or cast) to a 64 bit integral type first. Also, prefer using bit-wise shift operations on unsigned integral types.

unsigned char a = 0x00;
  unsigned char b = 0x00;
  unsigned char c = 0x00;
  unsigned char d = 0x00;
  unsigned char e = 0x00;
  unsigned char f = 0xbc;
  unsigned char g = 0x61;
  unsigned char h = 0x4e;

  unsigned long long aa = a ;
  unsigned long long bb = b ;
  unsigned long long cc = c ;
  unsigned long long dd = d ;

  unsigned long long int combination = (aa << 56) |(bb << 48) | (cc << 40) | (dd << 32) |
  (e << 24) | (f << 16) | (g << 8) | (h);
vijayan121 1,152 Posting Virtuoso

> What am I missing?

Making get_fields() a const member function.

vijayan121 1,152 Posting Virtuoso

> how to read input from strings using cin

1. Create a std::stringbuf which gets its input from a std::string.
2.Set this as the std::streambuf used by std::cin

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

int main()
{
    std::string input_string = "string containing input 123 45 a 72.45 etc." ;
    std::stringbuf streambuf( input_string, std::ios_base::in ) ;
    std::cin.rdbuf( &streambuf ) ;

    // now use std::cin to read the contents of input_string
}
wisaacs commented: excellent concise iostream example +1
mrnutty commented: Nice, I learned something new. +5
vijayan121 1,152 Posting Virtuoso

The result of a typeid expression is a std::typeinfo object representing the *type* of the expression.
Type of temp is an int, so typeid(temp) and typeid(4) both give typeid(int).

To check if the user entered an int or not, check the state of the stream after the attempted input. If an int could not be read, the stream would be put into a failed state.

if( !( cin >> temp ) ) throw 4 ;
vijayan121 1,152 Posting Virtuoso

Specify std::ios::ate as the file mode in the constructor.

Or if the file is already open, close it and reopen with std::ios::ate as the file mode.

vijayan121 1,152 Posting Virtuoso

<deleted>

vijayan121 1,152 Posting Virtuoso

A simple way:

struct A
{
    static A* create() { return new A() ; }
    
    // ...

    private:
        A( /* ... */ ) ;
        A( const A& that ) ;
        // ...
};

If that is too simple for your requirements, see:
Item 27: Requiring or prohibiting heap-based objects in 'More Effective C++' by Scott Meyers.
http://www.informit.com/store/product.aspx?isbn=020163371X

vijayan121 1,152 Posting Virtuoso

To export symbols from a shared library, you need to use the __declspec(dllexport) attribute as you have done.

A program that uses exported symbols from a DLL needs to import them using __declspec(dllimport).

It is usually a good idea to have a single header file for the shared library, which will declare the public symbols as __declspec(dllexport) when used in the library and as __declspec(dllimport) when used in a program that uses the library.

see: http://msdn.microsoft.com/en-us/library/8fskxacy%28VS.80%29.aspx
and http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c9855

vijayan121 1,152 Posting Virtuoso

std::sort is an overloaded function, and this can cause problems with some compilers.
see: http://www.boost.org/doc/libs/1_37_0/libs/bind/bind.html#err_overloaded

The work-arounds are simple; this is one way:

typedef std::vector<int>::iterator iterator ;
void (*sort_function)( iterator, iterator ) = &std::sort ;
thg.create_thread( boost::bind( sort_function,
                                mass.begin(), mass.end() ) ;
vijayan121 1,152 Posting Virtuoso

This is how I would do it. O(N log N) time.

a. Keep track of the line number as the lines are read into a vector.
b. Sort on the string (part that is to be checked for duplicates)
c. Partition into unique and non-unique lines (on the string)
d. Sort the unique lines on line number

#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>

struct csv
{
    int line_number ;
    std::string first ;
    std::string rest ;

    csv( const std::string& line )
    {
        static int n = 0 ;
        line_number = ++n ;
        std::istringstream stm( line ) ;
        std::getline( stm, first, ',' ) ;
        std::getline( stm, rest ) ;
    }

    bool operator == ( const csv& that ) const
    { return rest == that.rest ; }

    bool operator < ( const csv& that ) const
    { return rest < that.rest ; }
};

struct cmp_line_number
{
    bool operator() ( const csv& first, const csv& second ) const
    { return first.line_number < second.line_number ; }
};

int main()
 {
     std::vector< csv > csvs ;
     {
       std::string line ;
       std::ifstream file_in( "has_dups.csv" ) ;
       while( std::getline( file_in, line ) ) csvs.push_back(line) ;
     }

     std::sort( csvs.begin(), csvs.end() ) ;
     typedef std::vector< csv >::iterator iterator ;
     iterator end = std::unique( csvs.begin(), csvs.end() ) ;
     std::sort( csvs.begin(), end, cmp_line_number() ) ;

     std::ofstream file_out( "no_dups.csv" ) ;
     for( iterator iter = csvs.begin() ; iter != end ; ++iter )
        file_out<< iter->first << ',' << iter->rest << '\n' ;
 }
vijayan121 1,152 Posting Virtuoso

This paper by Stroustrup addresses some of the issues raised in this thread. Well worth a read, IMHO.
http://www.research.att.com/~bs/new_learning.pdf

vijayan121 1,152 Posting Virtuoso

> Size and speed aren't really an issue here, just ease of use.
> Using std::strings as well would be beneficial.

You might want to have a look at TinyXML.
http://www.grinninglizard.com/tinyxml/

And perhaps TinyXML++, which leverages more C++ strengths.
http://code.google.com/p/ticpp/

vijayan121 1,152 Posting Virtuoso

> Is there a safe and legal way to go from a pointer to a member of an object
> to a pointer to that same object?

No.

A pointer to a member is a pointer to a member of a class, not a pointer to a member of an object. When you dereference a pointer to a member of a class, you need you need to provide an object of that class with respect to which it is derefenced.

The object comes into picture only when the pointer to member is dereferenced; the same pointer to member can be dereferenced many times, each time with a different object.

vijayan121 1,152 Posting Virtuoso

You need a pthread_cond_wait( &c_threshold_cv, &m_mutex ) ; in your consumer thread.

See: http://www.ibm.com/developerworks/linux/library/l-posix3/
And: http://www.ibm.com/developerworks/linux/library/l-posix3/

vijayan121 1,152 Posting Virtuoso

Define the static member variables that have been declared.

namespace fun{
        // ...
        class driver{
                // ...
            	static int size;
            	static int eff;
            	static int idnumber;
                static std::vector<int> bmv;
                static std::vector<int> amv;
                static std::vector<int> bbv;
                static std::vector<int> abv;
                // ...
        };
        // ...
}
// ...

int fun::driver::size = 22 ;
int fun::driver::eff = 'F' ;
int fun::driver::idnumber = 77 ;
std::vector<int> fun::driver::bmv ;
std::vector<int> fun::driver::amv( 10U ) ;
std::vector<int> fun::driver::bbv ;
std::vector<int> fun::driver::abv ;

// ...
vijayan121 1,152 Posting Virtuoso

> error: ‘numeric_limits’ was not declared in this scope

#include <limits>

> error: ‘streamsize’ was not declared in this scope

std::streamsize

vijayan121 1,152 Posting Virtuoso
vijayan121 1,152 Posting Virtuoso

In this function

CEntityFactoryDictionary EntityFactoryDictionary( )
{
  static CEntityFactoryDictionary s_EntityFactoryDictionary;
  return s_EntityFactoryDictionary;
}

You are returning (by value) an anonymous temporary object which is a copy of the static s_EntityFactoryDictionary; you call InstallFactory on this anonymous temporary object which is immediately destroyed after that.

Modify the function as:

CEntityFactoryDictionary[B]&[/B] EntityFactoryDictionary( )
{
  static CEntityFactoryDictionary s_EntityFactoryDictionary;
  return s_EntityFactoryDictionary;
}

and you should be ok.

Caveat: I haven't looked at the rest of your code.

vijayan121 1,152 Posting Virtuoso

do you mean in findpath.h i write it like this

extern int map[]

Yes.

and in area.cc i make it like this?

int map[]

No. Like this:

int map[ MAP_WIDTH * MAP_HEIGHT ] = 
{

// 0001020304050607080910111213141516171819
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,   // 00
	1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,1,   // 01
	1,9,9,1,1,9,9,9,1,9,1,9,1,9,1,9,9,9,1,1,   // 02
	1,9,9,1,1,9,9,9,1,9,1,9,1,9,1,9,9,9,1,1,   // 03
	1,9,1,1,1,1,9,9,1,9,1,9,1,1,1,1,9,9,1,1,   // 04
	1,9,1,1,9,1,1,1,1,9,1,1,1,1,9,1,1,1,1,1,   // 05
	1,9,9,9,9,1,1,1,1,1,1,9,9,9,9,1,1,1,1,1,   // 06
	1,9,9,9,9,9,9,9,9,1,1,1,9,9,9,9,9,9,9,1,   // 07
	1,9,1,1,1,1,1,1,1,1,1,9,1,1,1,1,1,1,1,1,   // 08
	1,9,1,9,9,9,9,9,9,9,1,1,9,9,9,9,9,9,9,1,   // 09
	1,9,1,1,1,1,9,1,1,9,1,1,1,1,1,1,1,1,1,1,   // 10
	1,9,9,9,9,9,1,9,1,9,1,9,9,9,9,9,1,1,1,1,   // 11
	1,9,1,9,1,9,9,9,1,9,1,9,1,9,1,9,9,9,1,1,   // 12
	1,9,1,9,1,9,9,9,1,9,1,9,1,9,1,9,9,9,1,1,   // 13
	1,9,1,1,1,1,9,9,1,9,1,9,1,1,1,1,9,9,1,1,   // 14
	1,9,1,1,9,1,1,1,1,9,1,1,1,1,9,1,1,1,1,1,   // 15
	1,9,9,9,9,1,1,1,1,1,1,9,9,9,9,1,1,1,1,1,   // 16
	1,1,9,9,9,9,9,9,9,1,1,1,9,9,9,1,9,9,9,9,   // 17
	1,9,1,1,1,1,1,1,1,1,1,9,1,1,1,1,1,1,1,1,   // 18
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,   // 19

};
vijayan121 1,152 Posting Virtuoso

Write three 'main' functions, one in each file.

int ProgramList_main( int argc, char** argv ) ;
int MD5Hash_main( int argc, char** argv ) ;
int HazardCheck_main( int argc, char** argv ) ;

Then write a single real main function, which calls these one after another:

int main( int argc, char** argv )
{
   int exit_code = ProgramList_main( argc, argv ) ;
   if( exit_code == 0 ) exit_code = MD5Hash_main( argc, argv ) ;
   if( exit_code == 0 ) exit_code = HazardCheck_main( argc, argv ) ;
   return exit_code ;
}
vijayan121 1,152 Posting Virtuoso

Instead of defining it here, as

int map[ MAP_WIDTH * MAP_HEIGHT ] =
{
   // ...
};

Just declare it in this file

extern int map[] ;

(And then define it in the implementation file of area, eg. area.cc)

vijayan121 1,152 Posting Virtuoso

1. Declare each template friend function before the definition of template class. (#include of the header, as you have will do).

2. Add <> in the friend declarations.

template <class T> class UList ;

template <typename T > void sort( UList<T>& ) ;

template <typename T >
std::ostream& operator << ( std::ostream&, const UList<T>& ) ;


template < typename T >  class UList
{
  public:

    friend std::ostream& operator << [b]<>[/b] ( std::ostream&, const UList<T>& ) ;

    friend void sort [b]<>[/b] ( UList<T>& ) ;
    
    // ...
} ;

See http://www.parashift.com/c++-faq-lite/templates.html#faq-35.16

vijayan121 1,152 Posting Virtuoso
vijayan121 1,152 Posting Virtuoso

Well, you could start with these two and then follow the links given in them.

http://antivirus.about.com/od/whatisavirus/a/virussignature.htm

http://en.wikipedia.org/wiki/Anti-virus_software

vijayan121 1,152 Posting Virtuoso

> But how do I go thru A folder and get all the files size's that are inside?

See: http://www.daniweb.com/forums/post342872.html#post342872

That just prints the native_file_string. To get the file size, construct a boost::filesystem::path from iter->native_file_string() and then use boost::filesystem::file_size on it, as in your current code.

vijayan121 1,152 Posting Virtuoso
void Example::function1( const Example& ex )
{
    // copy of the object on which function1 is called
    Example copy_of_this( *this ) ;

    /* whatever */

}
vijayan121 1,152 Posting Virtuoso

simply

int main()
{
    Example doe;
    
    doe.function1(doe);
}

or

int main()
{
    Example doe;
    Example water(doe);
    
    doe.function1(water);
}
vijayan121 1,152 Posting Virtuoso

Windows operating systems: Write your program and run it as an NT service
http://www.commsoft.com/services.html

Unix and unix like operating systems: Daemonize your program and run it as a unix daemon.
http://www.enderunix.org/docs/eng/daemon.php

vijayan121 1,152 Posting Virtuoso

Change line 32 to use fabs instead of abs (why?)

while ( fabs(high - low) > epsilon ) {

Ideally, also change the type of all the floating point numbers to double instead of float (why?)

And you should be ok.

vijayan121 1,152 Posting Virtuoso
void Example::function1( const Example& ex )
{
    Example copy_of_ex( ex ) ;

    /* whatever */

}
vijayan121 1,152 Posting Virtuoso
class cIsBad : public [b]std::[/b]unary_function <T, bool> {
vijayan121 1,152 Posting Virtuoso

> After spending more than a year learning C++ , I now realise that
> I still don't know it enough to program safely with that language.

That is almost certainly incorrect. To be able to program well (safely, elegantly, efficiently) in a language does not imply that you have to know 'everything' about the language.

To quote Stroustrup:

What design and programming techniques do we want to emphasize? What subsets of the language do we want to learn first? What subsets of the language do we want to emphasize in real code?

...

Even for the professional programmer, it is impossible to first learn a whole programming language and then try to use it. A programming language is learned in part by trying out its facilities for small examples. Consequently, we always learn a language by mastering a series of subsets. The real question is not ‘‘Should I learn a subset first?’’ but ‘‘Which subset should I learn first?’’

...

The emphasis for both novices and experienced programmers should be concepts and techniques. The syntactic and semantic details of C++ are secondary to an understanding of design and programming techniques that C++ supports.

- from http://www.research.att.com/~bs/new_learning.pdf

> Even more depressing is that EVEN a company like Microsoft with
> billions of dollars of spending in research, easy access to any
> computer scientist in the world, can't figure correctly how C++ works.

Not really. The Microsoft C++ team has known …

vijayan121 1,152 Posting Virtuoso

use std::find_if to locate the right position to insert the new item.
For example:

#include <iostream>
#include <functional>
#include <algorithm>
#include <list>
#include <iterator>

struct Ctest
{
    Ctest( double fv ) : fVal(fv) /* .... */ { /* ... */ }

    // ...

    [b]bool operator > ( const Ctest& that ) const
    { return this->fVal > that.fVal ; }[/b]

    operator double () const { return fVal ; }

    // ...

    private:
       double fVal ;

       // ...
};

int main()
{
  using namespace std ;

  list<Ctest> Clist ;

  double fval ;
  while( cout << "? " &&  cin >> fval )
  {
      [b]Clist.insert( find_if( Clist.begin(), Clist.end(),
                             bind2nd( greater<Ctest>(), fval ) ),
                    fval ) ;[/b]

      copy( Clist.begin(), Clist.end(),
                  ostream_iterator<double>( cout, "->" ) ) ;

      cout << "null\n" ;
  }
}
vijayan121 1,152 Posting Virtuoso

> the problem lies with the implicit assignment int T::*PM to &B::i
> when the template is instantiated at compile-time.

Well, no assignment to an l-value is possible at compile time. At compile time, the constant expression &B::i is specified as the second template parameter.

A pointer to member constant expression shall be created using the unary & operator applied to a qualified-id operand, optionally preceded by a pointer to member cast

> At that point B is not well formed
B is just an incomplete type at that point. There is nothing in B so far to make it ill-formed.

> therefore the compiler don't know what B::i is and therefore complains:
The compiler knows (or ought to know) at that point that B::i is a non-static public member of B of type int.

The potential scope of a name declared in a class consists not only of the declarative region following the name's declarator, but also ...{elided}.

A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S.

> The nested class is: A< B, &B::i > which is being instantiated INSIDE B.
> The enclosing class here is B.

No.

A class defined within another is called a nested class. The name of a nested class is local to its enclosing class. The nested class is in the scope of its enclosing class. Except …

vijayan121 1,152 Posting Virtuoso

> Problem! That code WON'T compile in microsoft visual C++ 2008
> issuing specifically the C2327 compiler error:
> "'symbol' : is not a type name, static, or enumerator
> Code within a nested class attempts to access a member of the
> enclosing class that is not a type name, a static member, or an enumerator

Clearly, that is a spurious error message. In that code, there is no nested class is at all, and therefore there is no enclosing class either.

The IS clearly states that:

After the point of declaration of a class member, the member name can be looked up in the scope of its class. [Note: this is true even if the class is an incomplete class.]

It also gives an example (elided for clarity):

class Y;
char Y::* pmc;

declares pmc to be a pointer to a member of Y of type char. The declaration of pmc is well-formed even though Y is an incomplete type.

The code compiles cleanly under various versions of the GNU compiler, the Comeau compiler and other compilers with an EDG front end. AFAIK, the Microsoft C++ compiler which does not compile it is non-conforming for this case.

vijayan121 1,152 Posting Virtuoso

1) The iterator
a) why do you have a last_element member? Why don't you just return NULL for the before first element or after last element? I suspect you might have done that because of reverse iterations but even then I don't see why the much simpler NULL wouldn't work just as well.

The iterator corresponding to end is one which 'point to' a fictitious one past the last element of the sequence. This iterator must be well defined; --end should move the iterator to the last element of the sequence

b) why didn't you just put the insert_into_list and remove_into_list function INSIDE the iterator?

Insert and erase are logically operations on sequences; not operations on an iterator which just identifies one element of a sequence. Of course it is possible to create a pseudo sequence container and put insert and erase and other container operations into it.

2) I would have like you to have your opinion on a possible future revision of C++ to permit the pointer_to_member inside its own class

A pointer to member inside its own class is already allowed. eg.

template< typename T, int T::*PM > struct A {} ;
struct B
{
    int i ;
    A< B, &B::i > a ;
};

3) You seem to confirm that the last suggestion I proposed is the best approach, and you also mentionned "polymorphic call wrappers": I would be delighted to hear more about what that is! Do you mean to replace …