vijayan121 1,152 Posting Virtuoso

This is usually a result of catastrophic backtracking.
http://www.regular-expressions.info/catastrophic.html

vijayan121 1,152 Posting Virtuoso

There is a problem with this code:

vector<x*>::iterator iter;
 for(iter=x.begin();iter!=x.end();++iter)
 {
     delete *iter;
     x.erase(iter); // once the element is erased, the iterator is no longer valid
     // ++iter now will cause undefined behaviour. 
 }

Instead, you could use the value returned by erase:

vector<x*>::iterator iter;
 for( iter=x.begin() ; iter!=x.end() ; iter = x.erase(iter) )
 {
     delete *iter;
 }

This is perhaps the simplest way to do it:

for( auto ptr : x ) delete ptr ;
x.clear() ;
vijayan121 1,152 Posting Virtuoso

Really good, MandrewP.

Pity that the way this site is moderated, that post will get buried, never to see the light of day again.

vijayan121 1,152 Posting Virtuoso

Get rid of this:

Aligned16Vector::Aligned16Vector()
{
    vector<T,Allocator16<T>>::vector(); // why?
    // what is the purpose of constructing this anonymous object, 
    // which is immediately destroyed thereafter?
}

And as already mentioned, this: myVector.~Aligned16Vector(); and things would work out fine.

> The Allocate/Delete calls do add up just the order is a bit wonky.
> Seems it prints a buffer of size 1 to store data by default, but you delete that with the reserve
> then create a new one. There is another call to of size 1.
> I think it might be a temporary cache for stuff like switching or copying.

Ah, the joys of Microsoft's checked iterators! Just turn the damn thing off; #define _SECURE_SCL 0 IIRC.

> Reserve I think translates to
> Allocate new buffer
> copy from old to new
> Delete old buffer

It is a little more elaborate - one needs to take advantage of move semantics if possible, and if move is not possible then take care of exceptions which may be thrown by the copy constructor.

A reference implementation of reserve would look like:

template< typename T, typename A > void std::vector<T,A>::reserve( size_type n )
{
    if( n > capacity() )
    {
        pointer temp = A::allocate( n ) ;
        size_type i = 0;
        try
        {
            for( ; i < size() ; ++i )
                 new ( temp + i ) value_type( std::move_if_noexcept( (*this)[i]) ) );
        }
        catch(...)
        {
            while( …
vijayan121 1,152 Posting Virtuoso

To read a line of text, use std::getline() http://www.cplusplus.com/reference/string/getline/

To do something with every non blank line in the text file:

std::string line ;
while( std::getline( in_file, line ) && !line.empty() )
{
   // do something with line
}

To parse a line that has been read, use a std::istringstream. For example:

std::string line ;
while( std::getline( in_file, line ) && line != "end" )
{
   std::istringstream stm(line) ;
   std::string ac_name ;
   int year ;
   double balance ;
   double rate ;
   if( stm >> ac_name >> year >> balance >> rate )
   {
       // do something with them
   }
}
vijayan121 1,152 Posting Virtuoso
vijayan121 1,152 Posting Virtuoso

You have just one vector: vector<SurveyInfo> List; defined in main()

A copy of this one vector is passed around, to functions like HighLow()

You could declare/define HighLow() this way, void HighLow( const vector<SurveyInfo>& List ); and you would not even be passing a copy.

vijayan121 1,152 Posting Virtuoso

>> Dragon: why don't you just call CreateProcess() in a loop and call it 10 times?

Just listen to the Dragon, and treat everything else as white noise.

This is almost certainly the problem you were asked to solve, but just fantasize for a moment that your program is to run on (an otherwise idling) machine with, say, sixteen processors, and these ten processes need to start running at about the same measurable instant in time. You could do something like this:

enum { N = 10 } ;
char path[] = "<path to executable image>" ;

PROCESS_INFORMATION pi ;
STARTUPINFO si ;
std::memset( &si, 0, sizeof(si) ) ;
si.cb = sizeof(si) ;
std::vector<HANDLE> threads ;

for( int i=0 ; i<N ; ++i )
{
   if( CreateProcess( path, nullptr, nullptr, nullptr, FALSE,
                      CREATE_SUSPENDED, nullptr, nullptr, &si, &pi ) )
   {
       CloseHandle( pi.hProcess ) ;
       threads.push_back( pi.hThread ) ;
   }
   SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ) ;
   std::for_each( threads.begin(), threads.end(), ::ResumeThread ) ;
   SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_NORMAL ) ;
   // ..

   WaitForMultipleObjects( threads.size(), &threads.front(), TRUE, INFINITE ) ;
   // ...
   std::for_each( threads.begin(), threads.end(), ::CloseHandle ) ;
}
xfbs commented: good job +2
vijayan121 1,152 Posting Virtuoso
void HighLow( vector<SurveyInfo> List /*[K]*/ ) // typo?
{
   if( List.empty() ) return ; // just to be safe
   
   int K;
   int Low = List[0];            
   int High = List[0];       

   for(K = 0 ; K < /*6*/ List.size() ; K++) // where did 6 come from?     
    if(List[K] < Low)
    Low = List[K];

   for(K=0 ;  K < /*6*/ List.size() ; K++)    
    if(List[K] > High)
    High = List[K];

   cout << "Lowest Temperature:  " <<Low << endl;
   cout << "Highest Temperature: "<< High << endl;

}
vijayan121 1,152 Posting Virtuoso

In most cases where typelists were used in old C++ (for example in tuple<>) , we do not need them any more - variadic templates would do the job better, and more efficiently too. As such, IMHO, libraries like Boost MPL would be rarely used; most of the verbose and somewhat intractable code in these libraries would eventually become thin wrappers over variadic parameter packs any way.

For example,

#include <tuple>

template< typename... TYPES > struct typelist {};

template< typename... TYPES > struct size {} ;
template< typename... TYPES > struct size< typelist<TYPES...> >
{ enum { value = sizeof...(TYPES) } ; } ;

template< typename T, typename... TYPES > struct push_front {} ;
template< typename T, typename... TYPES > struct push_front< T, typelist<TYPES...> >
{ typedef typelist< T, TYPES... > type ; } ;

template< typename... TYPES > struct pop_front {} ;
template< typename T, typename... TYPES > struct pop_front< typelist< T, TYPES... > >
{ typedef typelist<TYPES...> type ; } ;

template< unsigned int N, typename... TYPES > struct at {} ;
template< unsigned int N, typename... TYPES > struct at< N, typelist<TYPES...> >
{ typedef typename std::tuple_element< N, std::tuple<TYPES...> >::type type ; };

// .. etc
vijayan121 1,152 Posting Virtuoso

In general, to navigate through object-oriented types, use a dynamic down-cast or a dynamic cross cast.

Languages like C++, java or eiffel have limited support for object-oriented programming (they are very unlike smalltalk or self). For example, a static member function is not polymorphic at run time; virtual function signatures cannot be different (other than for co-variance of return types). Very often, if we attempt pure oops in these languages, we are forced to fall back on a dubious 'CObject' or 'object' as the base class of almost everything. Which we then use in much the same way as a C programmer uses void* - if a function returns an 'object', to use the result intelligently we need to look at the implementation of the function, like for a C function that returns a void*.

Even if we have an object-oriented hierarchy of types, if we need polymorphic behaviour for any thing other than virtual functions, the only flexible solution available is compile-time polymorphism - ergo CRTP and friends.

vijayan121 1,152 Posting Virtuoso

Have a look at LINPACK/LAPACK. The widely quoted FP benchmarks.

http://www.netlib.org/benchmark/linpackc
http://www.netlib.org/clapack/

vijayan121 1,152 Posting Virtuoso

Test immediately after (not before) reading a line.

while( /*! myfile.eof()*/ getline(myfile,buffer) )
{
    /*getline(myfile,buffer);*/
    // ...
vijayan121 1,152 Posting Virtuoso

volatile variables; so you would be measuring the total time for arithmetic operations as well as loads and stores from/to (cache) memory.
Is that your intent?

void foobar()
{
    static volatile float a = 1.5;
    static volatile float b = 1.6;
    
    a *= b ; // multiplication operation
    
    // assembly generated with
    // >g++47 -Wall -std=c++0x -pedantic -Werror -O3 -march=core2 -S -c
    
	//      flds	_ZZ6foobarvE1a  ; load a on to the fp stack 
	//      flds	_ZZ6foobarvE1b  ; load b on to the fp stack
	//      fmulp	%st, %st(1) ; multiply two values on top of the fp stack 
	//      fstps	_ZZ6foobarvE1a ; store result (on top of the fp stack) to a
    
}
vijayan121 1,152 Posting Virtuoso

Create two index files, perhaps?

keywords.idx for keywords with each line containing: keyword path, [ path... ]
jade aaron_rogers.txt brett_favre.txt calvin_johnson.txt
amethyst jahvid_best.txt mathew_stafford.txt
urgent tom_brady.txt tony_romo.txt
// etc

ordernumbers.idx with each line containing: ordernumber path
10237 aaron_rogers.txt
11384 brett_favre.txt
etc.

On program startup read keywords.idx into a std::map< std::string, std::vector<std::string> >, update it as entries are being made and on shutdown write it back to keywords.idx.

Likewise for ordernumbers.idx with a std::map< std::string, std::string >

Clinton Portis commented: very nice STL implementation +10
vijayan121 1,152 Posting Virtuoso
#include <limits>
#include <iostream>

int main()
{
    std::cout << "does the type double have a representation for positive infinity? "
              << std::boolalpha << std::numeric_limits<double>::has_infinity << '\n' ;

    // if the answer was true, representation of positive infinity.
    const double infinity =  std::numeric_limits<double>::infinity() ;

    // maximum possible [B]finite[/B] value.
    const double max_value = std::numeric_limits<double>::max() ;

    // they are obviously not equal
    std::cout << "is max_value equal to infinity? " << ( max_value == infinity ) << '\n' ;
}
vijayan121 1,152 Posting Virtuoso

It appears that

a. There are going to be a very large number of DataStruct and Action objects (since the memory footprint of DataStruct is quite small).

b. DataStruct objects are added, but never removed (since the key is based on the size of the map).

In that case, using both a std::map<> and a std::set<> is unnecessary; a std::vector<> (with the key as the position in the sequence) and a std::set<> would suffice.

Something like this:

struct DataStruct
{
    double xData, yData ;
    std::vector<DataStruct>::size_type keyVal ;
    friend bool operator< ( const DataStruct& a, const DataStruct& b ) ;
};


class MapClass
{
    static std::vector<DataStruct> seq ;
    static std::set<DataStruct> set ;

    public:
        typedef std::vector<DataStruct>::size_type pos_t ;

        static pos_t AddDataStruct( const DataStruct& ds )
        {
            auto iterator = set.find( ds ) ;
            if( iterator != set.end() ) return iterator->keyVal ;
            else
            {
                pos_t pos = seq.size() ;
                seq.push_back(ds) ;
                seq.back().keyVal = pos ;
                set.insert( seq.back() ) ;
                return pos ;
            }
        }

        static const DataStruct& get( pos_t pos ) { return seq[pos] ; }
};

class Action
{
   MapClass::pos_t dataKey ;

   void do_stuff()
   {
      const DataStruct& ds = MapClass::get(dataKey) ;
      // ...
   }
};

with some additional trickery, more memory can be saved - make the value_type of the std::set<> a position in the sequence held by std::vector<>

If Datastruct objects also need to be removed as the program is running, this won't work; you could use boost::bimap<> in that case.
http://www.boost.org/doc/libs/1_47_0/libs/bimap/doc/html/index.html


       
Jsplinter commented: excellent! +3
vijayan121 1,152 Posting Virtuoso

> could I make lambda expression play the trick like above?
> so I don't have to write another functor for small cases

Boost Phoenix has polymorphic lambdas.
And once there are polymorphic lambdas with support for lazy evaluation, no extra boiler plate is required:

#include <string>
#include <iostream>
#include <boost/phoenix/core.hpp>

template< typename T, typename U, typename FN > bool foo( T a, U b, FN fn )
{ return fn(a,b) <= fn(b,a) ; }

int main()
{
    using namespace boost::phoenix::arg_names ;

    auto plus = arg1 + arg2 ; // polymorphic lambda

    int i = 7, j = 9 ;
    double d = 3.456 ;
    std::string a = "abc", b = "defghijk" ;

    std::cout << plus(i,j) << ' ' << plus(i,d) << ' ' << plus(a,b) << '\n' ;

    std::cout << std::boolalpha << foo( i, d, plus ) << '\n' ;
}

C++ lamda expressions are monomorphic (polymorphic lambdas would have given more flexibility and expressive power). AFAIK, it was concepts that required lambdas to be monomorphic. With concepts, a constrained template should be able to use only other similarly constrained templates; asking for concept checks with lazy evaluation of constraints (which polymorphic lambdas would require) would have made the life of compiler writers extremely difficult. Concepts were eventually dropped, and supporting polymorphic lambdas in the absence of concepts would have been a fairly straightforward matter; however the clear intent is to definitely have concepts in the next standard ("in maybe five years" - Stroustrup).

mike_2000_17 commented: great info! +14
vijayan121 1,152 Posting Virtuoso

> is a wrapper of type_info
> A new class of c++11, but I am not sure this code could work or not

Aha!

Yes, it would definitely work. So says N2530. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2530.html

And thank you! Always grateful to someone who dispels my ignorance.

vijayan121 1,152 Posting Virtuoso

One way is for the binary function to also provides a metafunction rebind a la allocators.

template< typename T, typename U > struct my_fun // TODO: std::enable_if for std::is_integral
{
    bool operator() ( const T& a, const U& b ) const { return b != 0 && a%b == 0 ; }
    template< typename X, typename Y > struct rebind
    {
        typedef my_fun<X,Y> type ;
    };
};

template < typename T, typename U, typename FN > bool foo( const T& a, const U& b, FN fn )
{
    auto fn2 = typename FN::template rebind<U,T>::type() ;
    return fn(a,b) && fn2(a,b) ;
}

It is also a more generic mechanism; one is not restricted to just rebinding from <T,U> to <U,T>.

vijayan121 1,152 Posting Virtuoso
WaltP commented: What is it with BOOST? Is it the cure-all of all problems? -4
vijayan121 1,152 Posting Virtuoso

Assuming that base, derived_A, derived_B, derived_C are classes generated by the protocol buffer which we do not want to modify, something like this:

struct task
{
    virtual ~task() {}
    virtual void do_it() = 0 ;
};

struct A : derived_A, task { virtual void do_it() override { /* do it for derived_A */ } } ;

struct B : derived_B, task { virtual void do_it() override { /* do it for derived_B */ } } ;

struct C : derived_C, task { virtual void do_it() override { /* do it for derived_C */ } } ;

void tasks( base& temp ) { dynamic_cast<task&>(temp).do_it() ; }

Needless to say, instantiate objects of type A, B, C in place of derived_A, derived_B, derived_C


BTW, I hadn't seen this earlier at the time I made the earlier post:

> maybe type_index is not a bad choice

std::unordered_map< std::/*type_index*/type_info, std::function<void(base&)> > tasks;
 
	tasks[ typeid(derived_A) ] = []( base& ) { /*do something*/ };
	tasks[ typeid(derived_B) ] = []( base& ) { /*do something*/ };
	tasks[ typeid(derived_C) ] = []( base& ) { /*do something*/ };

This won't compile; std::type_info is not copyable or assignable

vijayan121 1,152 Posting Virtuoso

> The man pages on MinGW don't provide enough examples, and there aren't good guides online.

Have you looked at the MinGW wiki?
For instance, this entry: http://www.mingw.org/wiki/MSVC_and_MinGW_DLLs


> Comparing *nix shared-objects with Windows DLLs is comparing apples and oranges,
> they are completely different in almost every way
> (linking model, dynamic loading model, ABI specification, memory model, etc.).

The Unix/ELF and Windows/PE dynamic linking differ in several interesting ways; for example, Unix/ELF is far more flexible, while Windows/PE is more efficient. But these differences are largely irrelevant to how exceptions are propagated through the call stack.


> any system library that throws exceptions will only throw Windows SEH exceptions
> through DLL boundaries, never native C++ exceptions

msvcrt.dll throws C++ exceptions across DLL boundaries. For instance, it exports
void * __cdecl operator new(unsigned int) ; which throws std::bad_alloc.


> any system library ... ... but if you do your own DLL,
> you have to either do the translations before and after the boundary
> or use an error-code mechanism instead

This is absolute nonsense. As long as the DLL and the program using the DLL do not violate the basics of the separate compilation model - compile and link with the same tool-chain, with the same or compatible switches - and do not violate fundamental rules like the ODR - for instance by having two different …

vijayan121 1,152 Posting Virtuoso

> keep track of the number of times that a given combination of words occurs in a file

Is a recursively nested map of unknown (at compile-time) depth the best data structure for this?

Use a variant of a trie (which also stores the count in each node) perhaps?
http://en.wikipedia.org/wiki/Trie

If required, in conjunction with the Aho–Corasick algorithm?
http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm

vijayan121 1,152 Posting Virtuoso

> I have a program written in C on LINUX environment.

The Linux environment (AFAIK) is emulated on Windows by Cygwin; cygwin dll and msvcrt.dll cannot be used together in the same program. The ABIs are different.
http://www.cygwin.com/faq/faq.programming.html#faq.programming.msvcrt-and-cygwin

You need to recompile. Or build the program (which uses the dll) with the Cygwin tool-chain.

> And if you have exceptions propagating across the module boundary
> (an exception thrown in the DLL propagating into the application code),
> then that is an error regardless of what languages or compilers or settings or whatever,
> exceptions should never be allowed to propagate across a module boundary
> (that's a fundamental rule when programming DLLs)

If it were so, libstdc++.so or libboost_thread.so would be examples of fundamental programming errors. As in everything else, what is required is that the library and the program using the library have to be ABI compatible.

vijayan121 1,152 Posting Virtuoso

Shouldn't you be using a virtual function instead of dispatching on type looked up at run-time?

The lifetime of the object returned by typeid() is guaranteed by the standard, so the following would work:

void foo( base& b ) { derived_A& a = dynamic_cast<derived_A&>(b) ; /* ... */  }
void bar( base& ) { /* ... */ }
void baz( base& ) { /* ... */ }

struct cmp_typeinfo
{
    bool operator() ( const std::type_info* a, const std::type_info* b ) const
    { return a->before(*b) ; }
};


void tasks( base& temp )
{
    static std::map< const std::type_info*, std::function< void( base& ) >,
                     cmp_typeinfo > dispatch_table =
    {
        { &typeid(derived_A), foo },
        { &typeid(derived_B), bar },
        { &typeid(derived_C), baz },
        // ...
    };

    dispatch_table[ &typeid(temp) ]( temp ) ;
}
vijayan121 1,152 Posting Virtuoso

> can I use this DLL now without recompiling my C code

No.

The ABIs (an ABI specifies things like data size, alignment, calling convention, binary formats of programs, object files and libraries, name decoration, exception propagation and so on) are different.

vijayan121 1,152 Posting Virtuoso

See Chapter 6: 'Insulation. Specific techniques for reducing compile-time dependencies' in 'Large-Scale C++ Software Design' by John Lakos
http://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/product-description/0201633620

Also presented as Items 26 to 30 of 'Exceptional C++' by Herb Sutter.
http://www.pearsoned.co.uk/bookshop/detail.asp?item=171019

vijayan121 1,152 Posting Virtuoso

> Where did you get that quote from?

A Microsoft Knowlege Base article, circa 2005

> any global or static object (non-volatile or volatile) will be flushed before a write on any volatile object.
> I am correct in thinking this?

Yes, the documentation is pretty clear - in Microsoft C++ volatile enforces acquire and release ordering for all volatile variables as well as all non-volatile variables with a static storage duration.

This is usually all that you require. However, there are situations where sequentially consistent ordering is necessary.
See: http://www.justsoftwaresolutions.co.uk/threading/memory_models_and_synchronization.html

vijayan121 1,152 Posting Virtuoso

> 1) I can`t do what I intended to do initially if I use pure C++99. It is impossible.

It is impossible to do it in portable code. And you have to accept that the code generated would be largely sub-optimal.

> I could do it with C++11. (.... I won`t bet anything that Microsoft will make it happen anytime soon,...)

Perhaps sooner than you expect; I suppose they are interested in the performance of the code generated by their compiler. Converting all the libraries to exploit C++11 will take some time though.

In the interim, Anthony Williams' JustThread library is (commercially) available. http://www.stdthread.co.uk/

> My current C++ (VS2009) allows me to do what I want, actually very easily, simply because:
> a) the keyword "volatile" meaning has been changed to a proprietary-sort of meaning

Not really 'changed'. They have just added on non-standard semantics to volatile. As has every mainstream compiler writer; each one in a different way.

The Microsoft compiler treats volatile in the manner that Java (1.5+) does - close to volatile T being treated as C++11 would treat volatile std::atomic<T>

> so that it now actually means it will flush *everything I wanted to be flushed*: any temporary variable ...

I'm not too sure of that unless it has changed after 2005. This is what the Microsoft documentation used to say:

Declaring a variable as volatile prevents the compiler from reordering references to that …

vijayan121 1,152 Posting Virtuoso
struct tm* logTime ; // ***

You haven't got a struct tm; all you have is a pointer.


> How do I need to go about the actual conversion of that format into the struct?

Use a look-up table, perhaps?

const wchar_t* const month_names[12] = { L"Jan", L"Feb" /* , etc */ };
int m = 0 ;
for( ; m < 12 ; ++m ) if( memcmp( month, month_names[m], sizeof(month) ) == 0 ) break ;
struct tm log_time ;
log_time.tm_mon = m ;
vijayan121 1,152 Posting Virtuoso

The volatile keyword was introduced at the time when C had no notion of concurrency other than time-slicing on a single processor. The notion of volatile in C++ is the same as what it is in C.

This article by Myers and Alexandrescu is instructive: http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf

This is what they have to say about volatile:

One might hope that the above fully volatile-qualified code would be guaranteed by the Standard to work correctly in a multithreaded environment, but it may fail for two reasons.
First, the Standard’s constraints on observable behavior are only for an abstract machine defined by the Standard, and that abstract machine has no notion of multiple threads of execution. As a result, though the Standard prevents compilers from reordering reads and writes to volatile data within a thread, it imposes no constraints at all on such reorderings across threads. At least that’s how most compiler implementers interpret things. As a result, in practice, many compilers may generate thread-unsafe code from the source above. If your multithreaded code works properly with volatile and doesn’t work without, then either your C++ implementation carefully implemented volatile to work with threads (less likely), or you simply got lucky (more likely). Either case, your code is not portable.

And their conclusion:

Finally, DCLP and its problems in C++ and C exemplify the inherent difficulty in writing thread-safe code in a language with no notion of threading (or any other form of concurrency). Multithreading considerations are pervasive, …

vijayan121 1,152 Posting Virtuoso

> I think these facilities would make GP become much more convenient, atleast we have them become standards,
> so every decent compilers should support these features.

Yes, every decent compiler would (given an year or two) support these features.

The problem is that in the real world there are too many senile C++ "experts" who believe that education stops at graduation, and are averse to anyone using anything that they themselves have no desire to understand.

It takes time and patience; that is all. Over a reasonably short period of time, even the newbies realize that the world has moved on.

vijayan121 1,152 Posting Virtuoso

> I know how to send data in one struct and receive it on the other side, because there is constant size of structure.

Assuming that you are not converting to/from a common network data representation of the struct, this will work only if the POD struct involved has the same binary layout at both ends. This would be the case if both ends run on the same processor architecture, the same OS, are compiled with the same version of the same compiler and with the same compiler flags.

If for some absolutely compelling reason you decide to transmit POD structs in native binary form, and there is more than one such struct involved, one idea would be to wrap them in a discriminated union for send; and unwrap based on the type field after recv.

struct one { /*...*/ } ;
struct two { /*...*/ } ;
// ...

struct any
{
    enum struct_type { POD_ONE, POD_TWO /*, ... */ } ;

    any( const one& data ) : type(POD_ONE), pod_struct_one(data) {}
    any( const two& data ) : type(POD_TWO), pod_struct_two(data) {}
    // ...

    struct_type type ;
    union
    {
        one pod_struct_one ;
        two pod_struct_two ;
        // ...
    };
};
vijayan121 1,152 Posting Virtuoso
template< typename T > struct Node 
{
	/*struct*/ Node( T data )
	{
		this->data = data;
		previous = NULL;
		next = NULL;
	}
	T data;
	/*struct*/ Node *previous; // keyword struct is superfluous here
	/*struct*/ Node *next;
} /*NODE*/ ; 

template< typename T > class LinkedList
{
    protected:
	/*NODE*/ Node<T>* head;
	/*NODE*/ Node<T>* tail;
};
vijayan121 1,152 Posting Virtuoso

Initializer lists are part of standard C++, since August 2011 (when C++11 was formally accepted by a unanimous 21-0 vote). It was not there in the old standard (C++98 which has now been superseded).

vijayan121 1,152 Posting Virtuoso

Alternatively, use a pure object-oriented interface.

////////// header my_class.h ////////////////////////////
// include guard

#include <memory>

struct my_class
{
    static std::shared_ptr<my_class> create(int,int) ;

    virtual ~my_class() ;

    virtual int my_fun( int a, int b ) = 0 ;

    // virtual ... = 0 ;
    // virtual ... = 0 ;
};
////////// implementation my_class.cc ////////////////////////////
# include "my_class.h"

namespace
{
    struct my_class_impl : my_class
    {
        my_class_impl( int, int ) ;

        virtual int my_fun( int a, int b ) override ;

        // virtual ... override ;
        // virtual ... override ;
    };
    
    // my_class_impl member definitions
}

std::shared_ptr<my_class> my_class::create( int a, int b )
{ 
    return std::make_shared<my_class_impl>(a,b) ; 
}
vijayan121 1,152 Posting Virtuoso

Use std::initializer_list<>
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=424

#include <initializer_list>

template< typename T > void foo( std::initializer_list< std::initializer_list<T> > a )
{
    // ...
}

int main()
{
    foo( { { 1, 2, 3 }, { 4, 5, 6 } } ) ;
}
vijayan121 1,152 Posting Virtuoso

> Is it really hard to find someone who know how to make a good use of stl

No. AFAIK, STL (and in many cases boost) have been mainstream for some years.


> ... Like the way modern c++ design did?

Yes. 'Modern C++ Design' went beyond just making good use of STL. I think the techniuqes that Alexandrescu introduced are far from obvious to the vast majority of C++ programmers out there. It takes quite some getting used to, and poor diagnostic support from compilers and poor template debugging facilities don't help.

In practise, I think what would work is: start with specific (non-generic) solutions to specific programming problems, discover reusable abstractions over a period of time, and gently evolve towards a more generic refactoring of the design. Refactoring is something you have to do in real life, and conceptually refactoring (to) generic code is not any more difficult than refactoring (to) object-oriented code.

The situation with C++11 (type_traits, enable_if, polymorphic call-warppers and so on) in 2011 is no different from the situation in 1998 with respect to standard algorithms and function objects.

vijayan121 1,152 Posting Virtuoso

> would it be easier to write the file backwards instead of reading it backwards?

No.


If the file is small,

#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>

int main()
{
   std::ifstream file( __FILE__, std::ios_base::binary ) ;
   file >> std::noskipws ;

   typedef unsigned char byte ;
   std::istream_iterator<byte> bof(file), eof ;
   std::vector<byte> seq( bof, eof ) ;

   std::for_each( seq.rbegin(), seq.rend(), []( byte b ) { std::cout << b ; } ) ;
   std::cout << '\n' ;
}
vijayan121 1,152 Posting Virtuoso

If the file is small enough, read it into a std::vector<unsigned char> and use the container's reverse_iterator.

If it is big, either read it in chunk by chunk
or memory map the file http://www.freebsd.org/cgi/man.cgi?query=mmap

vijayan121 1,152 Posting Virtuoso
float num[3][3];

   std::cout << "Enter 9 numbers: ";

   for (int i = 0; i < 3; ++i )
      for( int j = 0 ; j < 3 ; ++j )
	 std::cin >> num[i][j];

   for (int i = 0; i < 3; ++i )
   {
      for( int j = 0 ; j < 3 ; ++j ) std::cout << num[i][j] << ' ' ;
      std::cout << '\n' ;
   }

See: http://www.cplusplus.com/doc/tutorial/arrays/

vijayan121 1,152 Posting Virtuoso

> how do I use the complete path like you said above, vijayan121?

See: http://en.wikipedia.org/wiki/Fully_qualified_file_name

On Windows, it would start with a drive letter; something like: std::fopen( "C:\\directory1\\directory2\\directory3\\input.txt", "r" ) ;

vijayan121 1,152 Posting Virtuoso

> Is there a specific location where I have to put my input.txt file?

Either place input.txt in the working directory of your program.

Or use a complete path like "C:\\some_dir\\etc\\etc\\input.txt" instead of a relative patch.

vijayan121 1,152 Posting Virtuoso

> I want to ether copy it to another location

#include <fstream>

int main()
{
    std::ifstream fin( "myfile.dat", ios_base::in|std::ios_base::binary ) ;
    std::ofstream fout( "myfile.cpy", ios_base::out|std::ios_base::binary ) ;
    fout << fin.rdbuf() ;
}

> or (more likely) send it through zlib's deflate.

Simplest if you use a C++ wrapper over zlib.
For example, using the Boost Iostream library http://www.boost.org/doc/libs/1_47_0/libs/iostreams/doc/index.html

#include <fstream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/zlib.hpp>

int main()
{
    std::ifstream fin( "myfile.dat", ios_base::in|std::ios_base::binary ) ;
    std::ofstream fout( "myfile.z", ios_base::out|std::ios_base::binary ) ;

    boost::iostreams::filtering_streambuf< boost::iostreams::output > stmbuf ;
    stmbuf.push( boost::iostreams::zlib_compressor() ) ;
    stmbuf.push(fout) ;

    boost::iostreams::copy( fin, stmbuf );
}
Ancient Dragon commented: good suggestions :) +17
vijayan121 1,152 Posting Virtuoso

> how about this?
> std::shared_ptr<A> pa = std::make_shared<A>() ;
> also more efficient than old semantic?

Yes, and for the same reason. Requires A to have an accessible default constructor, though.


> is it because the cause to copy the object of shared_ptr is very cheap?

shared_ptr<> hs move constructors and move assignment operators; it is extremely efficient when the source of the copy or assignment is a temporary or is no longer needed. In many other cases, the compiler would be able to apply copy-elision.

Even if a copy has to be made, it is quite cheap (copy a pointer and increment a reference count) if concurrency is not involved. If not, there would be a quality of implementation issue.

vijayan121 1,152 Posting Virtuoso

> any good suggestion about free, robust allocator which design for small objects?

Loki perhaps.
http://loki-lib.sourceforge.net/html/a00524.html

Also see: http://drdobbs.com/184402039

vijayan121 1,152 Posting Virtuoso

std::make_shared<> is just a wrapper over std::allocate_shared<> with the allocator defaulted to std::allocator<>.

Assuming there is a constructor A::A( int, const char*, double ) for A,

auto pa = std::make_shared<A>( 1, "hello", 22.8 ) ;

is more efficient when compared to

std::shared_ptr<A> pa( new A( 1, "hello", 22.8 ) ) ;

It requires only one memory allocation instead of two; storage for the objct and its shared reference count is allocated together.

mike_2000_17 commented: Nice! +14
vijayan121 1,152 Posting Virtuoso

> Is this safe?

Yes.

vijayan121 1,152 Posting Virtuoso

> I need to make a function that returns an array.

There is no way to return an array from a function (in either C or C++).

You can return a pointer to the first element of a dynamically allocated memory (which is messy). You could return a reference to an array (but the size must be known at compile time and its life-time needs to be correctly managed).

The sensible thing to do would be to return a std::vector<>. See:
http://pages.cs.wisc.edu/~hasti/cs368/CppTutorial/NOTES/CLASSES-INTRO.html#vector
http://www.mochima.com/tutorials/vectors.html