vijayan121 1,152 Posting Virtuoso
15. Use const proactively.

Summary

const is your friend. Immutable values are easier to understand, track, and reason about, so prefer constants over variables wherever it is sensible and make const your default choice when you define a value. It's safe, it's checked at compile time,
and it's integrated with C++'s type system.  ...


Discussion

Constants simplify code because you only have to look at where the constant is defined to know its value everywhere. Consider this code:

void Fun( vector<int>& v)
{  //...
   const size_t len = v.size();
   //... 30 more lines ...
}

When seeing len's definition above, you gain instant confidence about len's semantics throughout its scope (assuming the code doesn't cast away const, which it should not do). It's a snapshot of v's length at a specific point. Just by looking up one line of code, you know len's semantics over its whole scope. Without the const, len might be later modified, either directly or through an alias. Best of all, the compiler will help you ensure that this truth remains true.

...

From: 'C++ Coding Standards: 101 Rules, Guidelines, and Best Practices' by Sutter and Alexandrescu

vijayan121 1,152 Posting Virtuoso

The keys in the map are const objects: const std::string; they can't be modified directly inside the map.

Something like this, perhaps:

#include <iostream>
#include <map>
#include <string>
#include <cctype>

std::string to_lower( const std::string& str )
{
    std::string lc ;
    for( char c : str ) lc += std::tolower(c) ;
    return lc ;
}

std::map< std::string, std::string > to_lower( const std::map< std::string, std::string >& map )
{
    std::map< std::string, std::string > lc ;
    for( const auto& pair : map ) lc.emplace( to_lower(pair.first), to_lower(pair.second) ) ;
    return lc ;
}

int main()
{
     std::map< std::string, std::string > the_sms_codes
     {
        { ".02",  "Your (or my) two cents worth" },
        { "10X",  "Thanks" },
        { "2MI",  "Too much information"},
        { "2U2",  "To You Too" },
        { "4COL", "For Crying Out Loud" }
     };

     the_sms_codes = to_lower(the_sms_codes) ;

     for( const auto& pair : the_sms_codes ) std::cout << pair.first << " - " << pair.second << '\n' ;
}

http://coliru.stacked-crooked.com/a/a8002a215a00beca

Or initialise them as lower case strings:

std::map< std::string, std::string > the_sms_codes
{
    { to_lower(".02"),  to_lower("Your (or my) two cents worth") },
    { to_lower("10X"),  to_lower("Thanks") },
    // ...
};
vijayan121 1,152 Posting Virtuoso

The canonical C++ way is to use templated callbacks in conjunction with:
wrapping the call in a polymorphic call wrapper std::function<>
and currying with std::bind()
http://en.cppreference.com/w/cpp/utility/functional/function
http://en.cppreference.com/w/cpp/utility/functional/bind

Sample code:
http://coliru.stacked-crooked.com/a/8d4283e68de561cf
http://rextester.com/VBNT79084

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

Read this first: http://www.cplusplus.com/articles/Gw6AC542/
Take your time; make sure you have understood it.

The structure of your code should be something like this:

file game.h

#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED

#include <string>
#include <vector>

class adventure ; // declare

class game
{
     struct PlayerScore {
            std::string name;
            int score;
     };

    std::vector<PlayerScore> scores ;

    public:

        // ...

        void addtoHallofFame( adventure a ) ; // declare, do not define

        // ...

};

#endif // GAME_H_INCLUDED

file adventure.h

#ifndef ADVENTURE_H_INCLUDED
#define ADVENTURE_H_INCLUDED

#include <vector>
#include <string>

class game ; // declare

class adventure {

    int score = 0 ;
    game& g ;

    public:
        adventure( game& the_game ) : g(the_game) { /* ... */ }

        // ...

        inline int getScore() const { return score ; }

        void update( const std::vector<std::string>& arr ) ; // declare, do not define

        // ...
        static const std::string quit_msg ; // this is just a declaration
};

#endif // ADVENTURE_H_INCLUDED

file game.cpp

#include "game.h"
#include "adventure.h" // class adventure is now defined

// ...

void game::addtoHallofFame( adventure a ) // define
{
    int adventureScore = a.getScore();

    std::string playerName;

    // ...

    PlayerScore p = { playerName, adventureScore } ;
    scores.push_back(p) ;
}

// ...

file adventure.cpp

#include "adventure.h"
#include "game.h" // class game is now defined

// ...

const std::string adventure::quit_msg = "quit" ; // define the static member in the cpp file

void adventure::update( const std::vector<std::string>& arr )
{

    if( !arr.empty() && arr.front() == quit_msg )
    // ...
    g.addtoHallofFame(*this) ; …
vijayan121 1,152 Posting Virtuoso

The problem with

{
    Game g;
    g.addtoHallofFame(*this);
}

is that g is a local variable at block scope (automatic storage duration); it will be destroyed when the scope is exited from.

One option would be to make vector<PlayerScore> scores; a static member of Game; this is logical if there can be only one game in progress at a time.

Another is to keep a reference to the associated Game as a member in the Adventure object.

Or to pass a reference to the associated Game as a parameter to update()

// favour a std::vector<std::string> or std::array< std::string, N > over raw arrays
// void Adventure::update( string arr[], Game& g )
void Adventure::update( const vector<string>& arr, Game& g )
{       
    if ( !arr.empty() && arr[0] == "quit" ) // ideally avoid the magic constant "quit"  
    {           
        g.addtoHallofFame(*this);
    }
}
vijayan121 1,152 Posting Virtuoso

Why the warning doesn't occur in C++?

The IS does not require that undefined behaviour must be diagnosed.

The macro #define msizeof(type) ((char*)(&type) - (char*)(&type - 1))
engenders undefined behaviour when used this way:

int main()
{
    int x;

    // msizeof(x) attempts to evaluate &x - 1 
    // *** this engenders undefined behaviour
    printf("%u %u\n", msizeof(x), sizeof(x));  
}

When an expression that has integral type is added to or subtracted from a pointer ...
<elided for brevity>
... If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

In contrast, changing the macro to: #define msizeof(type) ((char*)(&type + 1) - (char*)(&type))
which attempts to evaluate &x + 1 eschews undefined behaviour because of the special provision:

For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

mike_2000_17 commented: Makes a lot more sense! +14
vijayan121 1,152 Posting Virtuoso

i tried this simple function but it won't compile
constexpr int multiply( int x, int y ){ return x*y ; }

The November 2013 CTP will compile it.
http://www.microsoft.com/en-us/download/details.aspx?id=41151&751be11f-ede8-5a0c-058c-2ee190a24fa6=True&fa43d42b-25b5-4a42-fe9b-1634f450f5ee=True

vijayan121 1,152 Posting Virtuoso

This is a canonical way to flatten out arrays of more than one (runtime) dimension. (The code below is for three dimensions):

#include <vector>
#include <memory>

template < typename T > struct array_3d_flat
{
    array_3d_flat( std::size_t i, std::size_t j, std::size_t k,
                   const T& v = T() ) : data( i*j*k, v )
    {
        for( std::size_t m = 0 ; m < data.size() ; m += k )
            inner.push_back( std::addressof( data[m] ) ) ;

        for( std::size_t m = 0 ; m < inner.size() ; m += j )
            outer.push_back( std::addressof( inner[m] ) ) ;
    }

    // moveable, non-copyable
    array_3d_flat( const array_3d_flat<T>& ) = delete ;
    array_3d_flat<T>& operator= ( const array_3d_flat<T>& ) = delete ;
    array_3d_flat( array_3d_flat<T>&& ) noexcept = default ;
    array_3d_flat<T>& operator= ( array_3d_flat<T>&& ) = default ;

    T** operator[] ( std::size_t i ) { return outer[i] ; }
    T& operator() ( std::size_t i, size_t j, size_t k )
    { return outer[i][j][k] ; }

    const T** operator[] ( std::size_t i ) const ; // elided for brevity
    const T& operator() ( std::size_t i, size_t j, size_t k ) const ; // elided

    private:
         std::vector<T**> outer ;
         std::vector<T*> inner ;
         std::vector<T> data ;
};

Compiled code is here: http://coliru.stacked-crooked.com/a/7c570672c13ca3bf

vijayan121 1,152 Posting Virtuoso
int main(){

    vector<user> userDetails;
    // string line;
    string userName;
    string password;

    {
        // local scope: we do not want to keep 
        // the stream for longer than necessary
        ifstream readFile("userInfo.txt");

        // while(getline(readFile,line))   {
        // a line consists of just two ws-seperated tokens
        // we can directly read them into userName and password
        while( readFile >> userName >> password )   {
            // stringstream iss(line);
            // iss >> userName >> password;
            // user userInfoDetails(userName,password);

            // using the object anonymously makes for clearer code
            userDetails.push_back( user(userName,password) );
        }
        // readFile.close();
        // the destructor of the stream will close it
    }

    cout << "Before Deletion" << endl;
    for ( /*int*/ std::size_t i =0; i<userDetails.size(); i++) {
       cout << userDetails[i].getUserName() << " " 
            << userDetails[i].getPassword() << "\n";
    }

    cout << " " << endl;
    string name;
    cout << "Enter User Name to delete: ";
    cin >> name;
    cout << " " << endl;

    for (/*int*/ std::size_t i = 0; i<userDetails.size(); /* i++ */ ) {

            if(userDetails[i].getUserName() == name){
                 // userDetails.erase(userDetails.begin() + i);

                 // if we do not need to maintain an ordered sequence
                 // this is the canonical way to remove an element
                 // cheaper than: userDetails.erase(userDetails.begin() + i);
                 std::swap( userDetails[i], userDetails.back() ) ;
                 userDetails.pop_back() ;
                 // break ; // uncomment if there are no duplicated names
            }

            else ++i ; // increment only if the element at i is not erased
                 // if we have erased the element at position i,
                 // a new element has come into that position;
                 // and we …
Ancient Dragon commented: nice solution :) +14
vijayan121 1,152 Posting Virtuoso

Does this mean that if I have a .h file with a templated class in it I don't need to have inclusion guards on it?

No.

Long story short, templates are not subject to the linkage part of the One-Definition Rules. The same is true for functions that are marked as inline or as static (or appear in unnamed namespaces), which all have internal linkage.

The linkage rules do not change for either templates or inline functions (or both). For instance, by default an inline function, or a function template instantiation has external linkage.

Instead, the IS has a special proviosion in the ODR rules for inline functions and templates.

3.2/5 There can be more than one definition of a class type, enumeration type, inline function with external linkage, class template, non-static function template, static data member of a class template, member function of a class template, or template specialization for which some template parameters are not specified in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements.

Given such an entity named D defined in more than one translation unit, then
- each definition of D shall consist of the same sequence of tokens; and
- etc. ...

Note: because of the proviso: 'provided that each definition appears in a different translation unit', include guards are still required.

A simple way to check this is to have two different translation …

vijayan121 1,152 Posting Virtuoso

Depending on the character set that is being used internally, either char / std::string or wchar_t / std::wstring as appropriate.

To communicate with the outside world (for instance performing file i/o or communicating over the network), ideally use utf8 encoded chars and std::string or char16_t and std::std::u16string (which are utf16 encoded).

See: http://en.cppreference.com/w/cpp/header/codecvt
http://en.cppreference.com/w/cpp/locale/wbuffer_convert
http://en.cppreference.com/w/cpp/locale/wstring_convert

vijayan121 1,152 Posting Virtuoso

Canonical:

#include <memory>

namespace restricted
{
    struct A
    {
        virtual ~A() {}
        virtual int value_a() const { return a ; }

        protected:
            int a = 0 ;
            virtual void value_a( int i ) { a = i ; }
    };

    struct B : A
    {
        virtual int value_b() const { return b ; }

        protected:
            int b = 0 ;
            virtual void value_b( int i ) { b = i ; }
    };
}

namespace exposed
{
    struct A : restricted::A
    {
        using restricted::A::value_a ;
    } ;

    struct B : restricted::B
    {
        using restricted::B::value_a ;
        using restricted::B::value_b ;
    } ;
}

int main()
{
    auto exposed_a = std::make_shared<exposed::A>() ;
    int v = exposed_a->value_a() ;
    exposed_a->value_a(v) ; // fine, exposed

    auto exposed_b = std::make_shared<exposed::B>() ;
    v = exposed_b->value_a() ;
    exposed_b->value_a(v) ; // fine, exposed
    v = exposed_b->value_b() ;
    exposed_b->value_b(v) ; // fine, exposed

    std::shared_ptr<restricted::A> restricted_a(exposed_a) ; // fine, exposed::A => restricted::A

    v = restricted_a->value_a() ; // fine
    // restricted_a->value_a(v) ; // *** error **** restricted::A::value_a(int) is protected

    restricted_a = exposed_b ; // also fine, exposed::B => restricted::A

    std::shared_ptr<restricted::B> restricted_b(exposed_b) ; // fine, exposed::B => restricted::B

    v = restricted_b->value_a() ; // fine
    // restricted_b->value_a(v) ; // *** error **** restricted::B::value_a(int) is protected
    v = restricted_b->value_b() ; // fine
    // restricted_b->value_b(v) ; // *** error **** restricted::B::value_b(int) is protected
}

http://ideone.com/k0cA1O

vijayan121 1,152 Posting Virtuoso

given that it created the && move constructor, why couldn't it create some kind of reference re-assign operator?

C++11 did that with std::reference_wrapper<>. A small class provided by the library, which fills the syntactic gap. Without having to redefine C++98 references; without causing existing code to break.
http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper

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

int main()
{
    const std::list<int> lst { 5, 4, 9, 3, 1, 8, 0 } ;
    for( const int& i : lst ) std::cout << i << " (" << &i << ") "  ;
    std::cout << '\n' ;

    std::vector< std::reference_wrapper< const int > > vec( lst.begin(), lst.end() ) ;
    std::sort( vec.begin(), vec.end() ) ;
    for( const int& i : vec ) std::cout << i << " (" << &i << ") "  ;
    std::cout << '\n' ;
}

http://ideone.com/ldNu1U

vijayan121 1,152 Posting Virtuoso

how to disable this non standard exention Vla to get to correct results?

Compile with g++ -std=c++11 -pedantic-errors

With GCC 4.9:

    #include <stdexcept>
    #include <iostream>

    int foo( int arg )
    {
        int a[arg] = { 1, 2, 3, 4 } ;
        int s = 0 ;
        for( int v : a ) s += v ;
        return s ;
    }

    void bar( int arg )
    {
        try
        {
            std::cout << "try foo( " << arg << " ): " ;
            foo(arg) ;
            std::cout << "ok\n" << std::flush ;
        }
        catch( const std::exception& e ) { std::cerr << "exception - what: " << e.what() << '\n' ; }
    }

    int main()
    {
        bar(1) ;
        bar(4) ;
        bar(10) ;
        bar(-1) ;
    }

.

g++ -std=c++11 -pedantic-errors -Wall -Wextra test.cc && ./a.out
temp.cc: In function 'int foo(int)':
temp.cc:6:14: error: ISO C++ forbids variable length array 'a' [-Wvla]
      int a[arg] = { 1, 2, 3, 4 } ;
               ^  

.

g++ -std=c++1y -pedantic-errors -Wall -Wextra test.cc && ./a.out
try foo( 1 ): exception - what: std::bad_array_length
try foo( 4 ): ok
try foo( 10 ): ok
try foo( -1 ): exception - what: std::bad_array_length
vijayan121 1,152 Posting Virtuoso

Local runtime-sized arrays with automatic storage duration (with the undesirable features of C99 VLAs excluded, and support for aggregate initialization and range-based for loops included) will be part of C++14. http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3639.html

Note: Implementation support for VLAs has been made optional in C (C11).

C++14 wiil also have std::dynarray<> http://en.cppreference.com/w/cpp/container/dynarray

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

For std::regex_search() with iterators, the iterators must be for iterating over a sequence of characters.

Iterator through the vector tokens, pick up each std::wstring and then apply std::regex_search() on the sequence of characters in the string.

#include <fstream>
#include <vector>
#include <string>
#include <boost/regex.hpp> // testing with GCC 4.8, broken std::regex

int main()
{
    std::vector< std::wstring > tokens { L"abcd", L"eacchij", L"kmlnop", L"qrbcccst" } ;

    boost::wregex regex { L"[ab]c+" } ;

    for( const auto& wstr : tokens )
    {
        std::wcout << wstr ;
        boost::wsmatch results ;
        if( regex_search( wstr, results, regex ) ) std::wcout << L": " << results[0] ;
        std::wcout << L'\n' ;
    }
}

Output:

abcd: bc
eacchij: acc
kmlnop
qrbcccst: bccc

vijayan121 1,152 Posting Virtuoso

A far better list than anything you would find on this site:
http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list

tux4life commented: Very useful :) +13
vijayan121 1,152 Posting Virtuoso

There is no reason for that dynamic_pointer_cast to fail to compile, or the push_back to the vector for that matter. Whatever is causing this error is not your responsibility, it is that of Microsoft developers. Either file a bug report or see if they fixed it in VS2012 (november update).

Please don't file a bug report; std::dynamic_pointer_cast<> works as specified by the IS in VS 2010.
(IIRC correctly, it also worked correctly in VS 2008)

This last example is much more realistic to my actual code, is this not allowed? Is there any way I can do this? Does the non-concrete-ness of derived make any real difference at all?

It is allowed; there is nothing special that you have to do to make it work; and, no, non-concrete-ness of the class does not make any difference.

This code compiles (and runs) cleanly with VS 2011:

#include <memory> 
#include <iostream> 
#include <vector>

struct base { virtual ~base() {} virtual std::shared_ptr<base> clone() const = 0 ; } ;

struct derived_abstract : base {} ;

struct more_derived : derived_abstract
{ 
    virtual std::shared_ptr<base> clone() const 
    { 
        return std::make_shared<more_derived>( *this ) ; 
    }
};

int main() 
{ 
    std::shared_ptr<base> pb = std::make_shared<more_derived>() ; 
    std::shared_ptr<base> pb2 = pb->clone() ; 

    std::shared_ptr<derived_abstract> pd =
                          std::dynamic_pointer_cast<derived_abstract>(pb) ; 
    std::cout << pd.get() << '\n' ;

    std::shared_ptr<derived_abstract> pd2 = 
                          std::dynamic_pointer_cast<derived_abstract>(pb2) ; 
    std::cout << pd2.get() << '\n' ;

    std::vector< std::shared_ptr<derived_abstract> > seq ;
    seq.push_back( std::dynamic_pointer_cast<derived_abstract>( pb->clone() ) ) ; 
    seq.push_back( std::dynamic_pointer_cast<derived_abstract>( seq[0]->clone() ) ) ; 
    std::cout << seq.back().get() …
vijayan121 1,152 Posting Virtuoso

proper way to pass a temporary stream...
I'm disliking the std::stream's lack of copy constructors.
I know exactly what the problem is, but I don't know what I can do about it

The proper way is to move the temporary stream. Stream classes in C++ are moveable, but not copyable.

Some types are not amenable to copy semantics but can still be made movable. For example:

  • fstream
  • unique_ptr (non-shared, non-copyable ownership)
  • A type representing a thread of execution

By making such types movable (though still non-copyable) their utility is tremendously increased. Movable but non-copyable types can be returned by value from factory functions:

...
ifstream find_and_open_data_file(/* ... /);
...
ifstream data_file = find_and_open_data_file(/
... */); // No copies!
...

In the above example, the underlying file handle is passed from object to object, as long as the source ifstream is an rvalue. At all times, there is still only one underlying file handle, and only one ifstream owns it at a time.
.
Movable but non-copyable types can also safely be put into standard containers. If the container needs to "copy" an element internally (e.g. vector reallocation) it will move the element instead of copying it.
...
- http://www.artima.com/cppsource/rvalue.html

A simple example:

#include <iostream>
#include <fstream>
#include <string>
#include <utility>

struct push_back_reader
{
    // stm referes to an input file stream opened (and owned) by this object
    push_back_reader( const std::string& path2file ) 
                    : …
vijayan121 1,152 Posting Virtuoso

Can C++11's Mutexes be used for Inter-Process Communication? In other words, can it be used for shared memory and signalling an event?

C++11 does not have any inter-process functionality.

C++11 threading primitives (mutexes, atomics, etc) are just that - threading primitives. They know nothing about processes, and they are not a means of achieving inter-process communication. The IS makes no mention of processes or inter-process communication; the behaviour of C++11 objects when placed in trans-process shared memory is undefined.

I wanted a cross-platform way of doing so without doing #ifdef windows and ifdef linux, etc..

So I'm stuck with events?

No.
Boost.Interprocess http://www.boost.org/doc/libs/1_52_0/doc/html/interprocess.html
is portable across Windows and POSIX, and has a wide range of higher-level interprocess mechanisms.

vijayan121 1,152 Posting Virtuoso

Visual Studio 2010 was already ahead of GCC as far as the library was concerned - the Microsoft compiler already had UNICODE support (utf-8, UCS-2 and UCS-4 codecvt facets), basic C++11 threads, atomics amd fences, locales, regular expressions. All these important features are stil missing in GCC (though locales are avalable on linux). What Micrsoft lagged behind was in support for important core C++11 language features. As of November 2012, they have made rapid progress and are on par on those too.

Some six months back, when a like question was raised in Daniweb, I had enthusiastically recommended GCC over MIcrosoft (both were behind clang, 3.1 at that time, but clang with libc++ is not particularly easy for a breginner to build and install).

Today, the landscape has changed; both clang 3.2 with libc++ and VS 2012 (November update) are far ahead of GCC 4.8. This is politically unpalatable to many I am sure - it is disagreeable to an open source afficianado like me, who had consistently preferred GCC over VC++ till now. But however unpleasant it may be, that VC++ is ahead of GCC by some distance (as as a C++ compiler on Windows) happens to be the bitter truth.

vijayan121 1,152 Posting Virtuoso
struct A // non-copyable, moveable
{
    A() { /* ... */ }
    ~A() { /* ... */ }

    A( const A& ) = delete ;
    A& operator= ( const A& ) = delete ;

    A( A&& ) { /* ... */ }
    A& operator= ( A&& ) { /* ... */ return *this ; }
};

struct B // copyable, non-moveable
{
    B() { /* ... */ }
    ~B() { /* ... */ }

    B( const B& ) { /* ... */ }
    B& operator= ( const B& ) { /* ... */ return *this ; }

    B( B&& ) = delete ;
    B& operator= ( B&& )  = delete ;
};

struct C // non-copyable, non-moveable
{
    C() = default ;
    ~C() = default ;

    C( const C& ) = delete ;
    C& operator= ( const C& ) = delete ;

    C( C&& ) = delete ;
    C& operator= ( C&& )  = delete ;
};

why the example in the link shows a base class, and another class derived from it

Syntactic sugar.

struct non_copyable_non_moveable
{
    non_copyable_non_moveable() = default ;
    ~non_copyable_non_moveable() = default ;

    non_copyable_non_moveable( const non_copyable_non_moveable& ) = delete ;
    non_copyable_non_moveable& operator= ( const non_copyable_non_moveable& ) = delete ;

    non_copyable_non_moveable( non_copyable_non_moveable&& ) = delete ;
    non_copyable_non_moveable& operator= ( non_copyable_non_moveable&& )  = delete ;
};

struct my_class : private non_copyable_non_moveable
{
    // we do not have to do anything more to make my_class non-copyable and non-moveable
};
vijayan121 1,152 Posting Virtuoso

Visual Studio 2012 (November update).

Way ahead of GCC (the other major contender) in C++11 conformance - Microsoft has implemented almost everything in the standard.

clang 3.2 with its libc++ is on par with VS 2012; and it is somewhat more mature and stable in comparison. But it has to be built from sources; and installing it is not an easy task for everyone.

vijayan121 1,152 Posting Virtuoso

I want to give the customer a 'CurrentAccount' which is inherited from Account; and then store it in an array of Accounts.
How do I go about doing this?

You can't. Account acnts[10]; holds objects of type Account by value.
When you try to store an object of type CurrentAccount into that array it gets sliced.
http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c

Use an array of pointers to Account instead: Account* ptr_accts[10];

Note: Ideally std::shared_ptr<Account> or std::reference_wrapper<Account> depending on the storage duration; but this may be beyond what you have learned till now.

vijayan121 1,152 Posting Virtuoso

I'm not sure what you mean

While building the DLL and the exe, for both use the same shared (DLL) version of the C/C++ runtime library.
http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx

vijayan121 1,152 Posting Virtuoso

You need to link both the DLL and the exe to the same instance of the run-time library.

Ie. link both with the shared version of the standard library: either /MDd (Debug) or /MD (Release)

vijayan121 1,152 Posting Virtuoso

Something like this:

// C++11
std::string generate_file_name( const std::string& name, const std::string& college )
{
    static int slno = 0 ;
    return name + '_' + college + '_' + std::to_string( ++slno ) ;
}


// or C++98
std::string generate_file_name( const std::string& name, const std::string& college )
{
    static int slno = 0 ;
    std::ostringstream stm ;
    stm << name << '_' << college << '_' << ++slno ;
    return stm.str() ;
}
vijayan121 1,152 Posting Virtuoso

The singleton design pattern is unique in that it's a strange combination: its description is simple, yet its implementation issues are complicated. - Andrei Alexandrescu in 'Modern C++ Design'

If Animal is a singleton - that is a second object of type Animal cannot exist - its singletonness can be enforced by the class Animal and by the class Animal alone.

This is one typical way of ensuring that one - and only one - instance of an object of dynamic type 'some unknown derived class of Animal' can exist at any point of time.

    //////////////  animal.h ///////////////////

    struct Animal
    {
        static Animal& get_it() ;

        virtual ~Animal() ;
        virtual int age() const = 0 ;
        virtual void speak() = 0 ;

        Animal( const Animal& ) = delete ; // non-copyable
        Animal( Animal&& ) = delete ; // and non-movable

        protected: Animal() ;
    };

--------------------------------

//////////////  animal.cc ///////////////////

#include "amnimal.h"
#include <atomic>
#include <mutex>
#include <stdexcept>

namespace
{
    std::atomic<Animal*> singleton(nullptr) ;
    std::mutex guard ;
}

Animal::Animal() // a constructor of a derived class will invoke this constructor
{
    if(singleton) throw std::logic_error( "Animal is a singleton" ) ;
    else singleton = this ;
}

Animal::~Animal() { singleton = nullptr ; }

Animal& Animal::get_it()
{
    std::lock_guard<std::mutex> lock(guard) ;

    if( !singleton ) throw std::logic_error( "singleton instance not created" ) ;
    else return *singleton ;
}

------------------------------

///////////////// main.cc ///////////

#include "amnimal.h"
#include <iostream>

int main()
{
    struct Zebra : Animal
    {
        virtual int age() const override …
vijayan121 1,152 Posting Virtuoso
vijayan121 1,152 Posting Virtuoso

To read a whole line (including whitespace) into a string, use std::getline()
http://www.cplusplus.com/reference/string/getline/

To read the contents of a file, where each data set consists of the name of a state followed by three numbers, the code would be something like:

std::ifstream file ("list.txt") ;
std::string name_of_state ;
int number ;
int month ;
int year ;

// check success or failure *after* (and not before) the attempted input.
// this is idiomatic - while we have read some data successfully ...  
while( std::getline( file, name_of_state ) && file >> month >> year )
{
    // discard everything up to and including the next newline
    file.ignore( 1024, '\n' ) ; // *** see note below

    // validate month, year etc.

    // use the data that has been read.
}

Note: to understand why std::istream::ignore() is needed, see:
http://www.cplusplus.com/forum/general/69685/#msg372532

vijayan121 1,152 Posting Virtuoso

std::size_t defined in the header <cstddef> can store the maximum size of a theoretically possible object of any type (including array).

std::size_t is commonly used for array indexing and loop counting. Programs that use other types, such as unsigned int, for array indexing may fail on, e.g. 64-bit systems when the index exceeds UINT_MAX or if it relies on 32-bit modular arithmetic.

from: http://en.cppreference.com/w/cpp/types/size_t

vijayan121 1,152 Posting Virtuoso

Is such a thing possible?

Yes. You would find it easier to solve a bigger problem by breaking it down into a set of smaller problems, each of which is easy to solve. For example:

Problem : return a dynamically allocated array containing unique chars from the input array.

Sub-problem one: check if a char in the array is a duplicate char. Is it present at an earlier position in the array?

// is char at array[pos] a duplicate? (present at an earlier position in the array)
bool is_duplicate( const char array[], std::size_t pos )
{
    for( std::size_t i = 0 ; i < pos ; ++i )
       if( array[i] == array[pos] ) return true ;

    return false ;
}

Sub-problem two: How many unique characters are there in the input array?

// get a count of unique chars in the array
std::size_t count_unique( const char array[], std::size_t size )
{
    std::size_t unique_cnt = 0 ;

    for( std::size_t i = 0 ; i < size ; ++i )
        if( !is_duplicate( array, i ) )  ++unique_cnt ;

    return unique_cnt ;
}

The bigger problem can now be reduced to:
a. Determine the number of unique characters are there in the input array
b. Dynamically allocate an array of that many chars.
c. For each char in the input array, if it is not a duplicate, copy it to the result array

char* array_without_dups( const char array[], std::size_t size, 
                          std::size_t& no_dups_array_size ) …
vijayan121 1,152 Posting Virtuoso

The last line is matching, but because it thinks the array size is zero it drops out and states that it doesn't match.

Haven't looked at any of the logic except this:

while(inFile) // the file stream is not yet at eof after the last line has been read
    {
        inFile.getline(inputArray, 8,'\n'); // try to read one past the last line
        // getline fails; and the stream goes an eof state
        // but we proceed as if no error has occurred.
        // ...

The correct idiom to read every line in a stream checks for failure after (not before) attempted input:

    while( inFile.getline(inputArray, 8,'\n') ) // if we have read a line
        {
            // go ahead and do something with the line
            // ...

static const ET CAPACITY = 20; //Size of the array

What happens if you encounter a line that is longer than this?
Is there a compelling reasaon not to use std::string?

Use the standard library - people who say you don't 'learn' C++ by if you use the language library are people who haven't learned C++ yet.
Ignore them for your own good.

vijayan121 1,152 Posting Virtuoso

Do you can show me a non-vector solution.

Hmm.. Thesnippet I posted dores not use vectors; instead it uses C-style null-terminated arrays of char (and dynamically allocated memory). With annotatations:

// input: an array of char terminated by a null-character
// returns: a dynamically allocated array of unique chars in the input
//          terminated by a null-character

char* remove_duplicates_preserve_order( const char* cstr )
{
    // 1. get a count of the number of unique chars in the input array
    // ---------------------------------------------------------------

    bool already_seen[UCHAR_MAX] = { false } ; // to look up already seen chars 
    int cnt_unique = 0 ; // number of unique chars in the string

    // for every char in the input array till we encounter the null-character
    for( const char* p = cstr ; *p ; ++p ) 
    {
        const unsigned char u = *p ;

        // if we have not seen this char earlier, increment cnt_unique 
        // and set already_seen[u] to true
        if( !already_seen[u] ) { already_seen[u] = true ; ++cnt_unique ; }
    }


    // 2. allocate memory for the result (a null-terminated array of chars)
    // --------------------------------------------------------------------

    char* result = new char[ cnt_unique + 1 ] ; // + 1 for the null-termination 
    result[cnt_unique] = 0 ; // null-terminate result


    // 3. copy unique chars in the input array to the result array
    // -----------------------------------------------------------

    // look up table to check if we had alredy copied a char to the result
    bool already_copied[UCHAR_MAX] = { false } ;

    // for every …
WaltP commented: Nooooob, remember? Dynamic memory? C'mon!!! -3
vijayan121 1,152 Posting Virtuoso

but now the problem I am having that it only deletes repeated pairs not all repeats. How can I make it so that it deletes all the repeats in the word?

If you are allowed to have a different order of chars in the result, just sort the original array first and it will remove all the duplicates.

If not, you need a to lookup the duplicated values (perhaps using a set). Something like:

char* remove_duplicates_preserve_order( const char* cstr )
{
    bool already_seen[ std::numeric_limits<unsigned char>::max() + 1 ] = { false } ;
    int cnt_unique = 0 ;
    for( const char* p = cstr ; *p ; ++p )
    {
        const unsigned char u = *p ;
        if( !already_seen[u] ) { already_seen[u] = true ; ++cnt_unique ; }
    }
    char* result = new char[ cnt_unique + 1 ] ;
    result[cnt_unique] = 0 ; // null-terminate

    bool already_copied[ std::numeric_limits<unsigned char>::max() + 1 ] = { false } ;
    for( char* p = result ; *cstr ; ++cstr )
    {
        const unsigned char u = *cstr ;
        if( !already_copied[u] ) { already_copied[u] = true ; *p = *cstr ; ++p ; }
    }

    return result ;
}

If you are allowed to use C++, std::string in conjuction with std::set<> would make the code a lot shorter, and a lot cleaner.

vijayan121 1,152 Posting Virtuoso

In

string::const_iterator url_beg(string::const_iterator b, string::const_iterator e)
{
    static const string sep = "://";
    // ...    
    return e;
}

the value returned is always e (end). Instead, return an iterator to the begin of the url.
Something like:

string::const_iterator url_beg( std::string::const_iterator b,
                                std::string::const_iterator e )
{
    static const string sep = "://";
    string::const_iterator iter = std::search( b, e, sep.begin(), sep.end() ) ;
    if( iter != e ) while( iter != b && std::isalpha( iter[-1] ) ) --iter ;
    return iter ;
}
vijayan121 1,152 Posting Virtuoso

Some other options are,

OpenCV:

You could just use OpenCv's Mat class with an OpenCV primitive data type; and then just store 0 or 1 as the values.

cv::Mat matrix4( 100, 60, CV_8U ) ;

Standard C++ library:

    #include <vector>
    #include <bitset>

    // fixed width matrix of bits
    std::vector< std::bitset<100> > matrix(60); // matrix of 1/0 values
    // http://en.cppreference.com/w/cpp/utility/bitset

    // resizeable matrix of bool values
    std::vector< std::vector<bool> > matrix2( 60, std::vector<bool>(100) ) ;

Boost:

#include <vector>
#include <boost/dynamic_bitset.hpp>

// resizeable matrix of bits
std::vector< boost::dynamic_bitset<> > matrix3( 60, boost::dynamic_bitset<>(100) ) ;
// http://www.boost.org/doc/libs/1_51_0/libs/dynamic_bitset/dynamic_bitset.html
vijayan121 1,152 Posting Virtuoso
//////////////////// a.h //////////////////////////

class C ;

class A
{
    public:
        void setInfo(int age, C *ptrToC);
};


//////////////////// b.h //////////////////////////////

#include "a.h"

class B
{
    private:
        A exampleofA;
};


//////////////////// c.h /////////////////////////////////

#include "b.h"

class C
{
    public:
        void randomFunction();
    private:
        A secondexampleofA;
        B exampleofB;
};


/////////////////////// a.cc //////////////////////////

#include "a.h"
#include "c.h"

void A::setInfo( int age, C *ptrToC )
{
    ptrToC->randomFunction(); 
}

Note: #include guards etc. elided for brevity

vijayan121 1,152 Posting Virtuoso
CBase b;

void func_set(CBase *pb) 
// pb may point to an object which has the dynamic type of some derived class of CBase
{
    b = *pb; // the object *pb may be sliced here
}

See http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c

You probolly can get away with changing line 24 to
&b = pb;

&b is not an lvalue.

vijayan121 1,152 Posting Virtuoso

You should not be using a name like _FOO anywhere in your code.

A name like _fOO can be used except in the global unnamed namespace. Just make sure that the character following the leading underscore is a lower case character.

vijayan121 1,152 Posting Virtuoso

Dudes I am newbie to C++ and forums. I thought i was helping that dude.

Fair enough. Perhaps you should have waited till marius2010 demostrated that a genuine attempt to solve the problem was made.

Code snippets are a genuine aid in learning programming - one good snippet is worth a thousand words. There is no reason why you should completely refrain from posting them.

This has always been a forum where the oldies have grown senile and forgotten that they too were once newbies. At least as far as I am concerned, you just tried to help some one, and I for one appreciate that you tried to help.

WaltP commented: helping and doing their homework are two different things. You can help without writing *the* answer. -3
m4ster_r0shi commented: Wise words! +0
vijayan121 1,152 Posting Virtuoso

All this is (conforming) C++:

struct A
{
    // http://www.stroustrup.com/C++11FAQ.html#default
    // http://www.stroustrup.com/C++11FAQ.html#constexpr
    constexpr A() = default ; // x == 0, y == 0

    constexpr explicit A( int x ) : x(x) {} // A::x==x A::y==0

    A( int x, int y )
    {
        A::x = x ;
        this->y = y ;
    }

    private:
        int x = 0 ; // http://www.stroustrup.com/C++11FAQ.html#member-init
        int y = 0 ;
};

struct B
{
    // http://www.stroustrup.com/C++11FAQ.html#delegating-ctor
    constexpr B() : B(0,0,0) {}

    constexpr explicit B( int x ) : B(x,0,0) {}

    constexpr B( int x, int y ) : B( x, y, 0 ) {}

    constexpr B( int x, int y, int z ) : x(x), y(y), z(z) {}

    private:
        int x ;
        int y ;
        int z ;
};

struct C : B
{
    // http://www.stroustrup.com/C++11FAQ.html#inheriting
    using B::B ; // a is initialized with 9 when we use an inherited construtor

    constexpr C( int x, int y, int z, int a ) : B(x,y,z), a(a) {}

    private: int a = 9 ;
};
vijayan121 1,152 Posting Virtuoso

tellg() in my code as the function is not supported on the desired hardware.

What hardware? A std::istringstream holds a std::stringbuf and it does not use anything other than memory allocated with the standard allocator.

Have you tried printing out the result returned by tellg() on the string stream?

vijayan121 1,152 Posting Virtuoso

I'm interested in sorting a standard container called say 'first_container' via another container which has iterators pointing to the first container.

An indirect sort is useful in many situations

  • a sequence is immutable, but we want a sorted view of the sequence
  • we want to access the sequence in two ways - in the original order and in the sorted order
  • a sequence contains objects which are expensive to move around, and we want a sorted view

The options available are:

  • indirect sort with reference_wrappers
  • indirect sort with iterators
  • indirect sort with pointers

The code using reference_wrappers tends to be cleaner than the code using either pointers or iterators.

const std::list<int> seq = { 42, 24, 75, 65, 42, 53, 65, 75, 74, 63, 46, 52, 35 } ;
for( int v : seq ) std::cout << v << ' ' ; std::cout << '\n' ;
// 42 24 75 65 42 53 65 75 74 63 46 52 35

// indirect sort with reference wrappers
std::vector< std::reference_wrapper<const int> > ref_wrappers( seq.begin(), seq.end() ) ;
std::sort( ref_wrappers.begin(), ref_wrappers.end() ) ;
for( const auto& rw : ref_wrappers ) std::cout << rw << ' ' ; std::cout << '\n' ;
// 24 35 42 42 46 52 53 63 65 65 74 75 75

// indirect sort with iterators
using iterator = std::list<int>::const_iterator ;
std::vector<iterator> iters ;
for( auto iter = seq.begin() ; iter != seq.end() ; ++iter ) iters.push_back(iter) ;
std::sort( iters.begin(), iters.end(), …
gerard4143 commented: Nice detailed reply - Thanks +12
vijayan121 1,152 Posting Virtuoso

string::const_reverse_iterator rit = s.rbegin();
This should be outside the loop(just before the loop)

Yes.

And you need not go all the way to end(); upto the middle of the string would suffice.

Which would make the code equivalent to:

bool is_palindrome( const std::string& str )
{ return std::equal( str.begin(), str.begin() + str.size()/2, str.rbegin() ) ; }

http://en.cppreference.com/w/cpp/algorithm/equal

vijayan121 1,152 Posting Virtuoso

resolving _GLHook_wglSwapLayerBuffers by linking to _GLHook_wglSwapLayerBuffers@8

Hmm... Seems to have found a library built with the Microsoft toolchain instead of one built with the GCC toolchain. Shouldn't be a problem unless there is a major version mismatch. Personally, I wouldn't be happy about this, and would still put in the -L<search_for_library_here> linker options.

vijayan121 1,152 Posting Virtuoso

So my question is, why is it crashing?

container_Student_info::iterator iter = students.begin() ;
while(iter!=students.end())
{
        if(fgrade(*iter))
        {
            // ....
        }
        else
        {
            it = students.begin();  
            students.insert(it, *iter) ; // the iterator 'iter' is no longer valid
            // because we have modified (added a new item into) the container  
            // ..
            ++iter ; // this leads to undefined behaviour
        }
        // ...
vijayan121 1,152 Posting Virtuoso

The linker can't find the library files. You need to add one or more -L<path to library files> to the link command
http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Directory-Options.html#Directory-Options

For example: -LC:\MinGW\lib