顯示具有 BCB 標籤的文章。 顯示所有文章
顯示具有 BCB 標籤的文章。 顯示所有文章

2013年3月27日 星期三

typename in C++ with gcc


一般在使用template, 不管在function或class, 需要注意要typename的使用
在Windows的Compiler或許不一定會用到(例如BCB), 但在gcc下 如果沒有謹慎使用
很容易出現error


#include <map>
using namespace std;
template <typename T>
bool Sample0(const T& t)
{
   T tgt=100;
   return tgt == t;

}

template <typename T>
bool Sample1(const T& t)
{
   //T::bar * p; /* error here*/
   typename T::bar * p;

}

struct TestType {
   typedef int bar;
};


template<typename T>
class Sample2{
public:
    typedef int size_type ;
    T m_A;
    void funcSample2()
    {
        map<T , int> mapSample2;
        //map<T, int>::iterator Sample2itr;  /* error here*/
        typename map<T, int>::iterator Sample2itr;
    }
};

template<typename T>
class Sample3 : public Sample2<T>
{
public:
    typedef typename Sample2<T>::size_type size_type;
    //typedef Sample2<T>::size_type size_type;  /* error here*/
    void funcSample3()
    {
        size_type abc = 0;
    }
};

int main() {
//Sample 0 一般簡易使用, 不需要typename
  int a=0;
  Sample0(a);

//Sample 1
   TestType x;
   Sample1(x);

//Sample 2
   Sample2<int> smp2;
   smp2.funcSample2();

//Sample 3
   Sample3<int> smp3;
   smp3.funcSample3();
}

因為:: scope operator 接在它後面的可以是成員變數、函數或是
物件類型。
如果不加上typename的話,編譯器可能會將bar/iterator/size_type 誤認為成員變數。
(實際上bar/iterator/size_type是一個物件類型)
所以要加上typename,讓編譯器知道這個東西是一個物件類型。

2013年3月7日 星期四

lower_bound, upper_bound and sorted vector

#include <vcl.h>
#pragma hdrstop
#include <vector>
#include <string>
#include <iostream>
using namespace std;
typedef struct column_desc
{
    const char* Token;
    const char* Comment;
    int value;
}COLUMN_DESC;
//---------------------------------------------------------------------------
class TokenCompare { // 用於比較的類
    public:
    bool operator()(const COLUMN_DESC& lhs, // 用於排序的比較函數
        const COLUMN_DESC& rhs) const {
        return keyLess(lhs.Token, rhs.Token); // keyLess在下麵
    }

    bool operator()(const COLUMN_DESC& lhs, // 用於查找的比較函數
        const std::string& k) const // (形式1)
    {
        return keyLess(lhs.Token, k);
    }

    bool operator()(const std::string& k, // 用於查找的比較函數
        const COLUMN_DESC& rhs) const // (形式2)
    {
        return keyLess(k, rhs.Token);
    }


    private:
    bool keyLess(const std::string& k1, // “真的”
        const std::string& k2) const // 比較函數
    {
        return k1 < k2;
    }
};

#pragma argsused
int main(int argc, char* argv[])
{
    COLUMN_DESC column[]={
    { "sdfg" , "sdfsdfsdf" , 9},
    { "abcd","abcdabcd" ,1},
    { "aeecd","eeecdeeecd" ,3},
    { "aeecd","eee1cdeeecd" ,5},
    { "aeecd","eee2cdeeecd" ,7},
    { "aaaa","aaaaaaaa" ,13},
    { "efef","efefefefefef" ,11},
    { "0000","dfdfdfdfdf" ,1},
    };
    std::vector<COLUMN_DESC> vvv;
    unsigned int colsz = (sizeof(column) / sizeof(column[0]));
    for ( int ii = 0 ; ii < colsz ; ii++)
    {
        std::vector<COLUMN_DESC>::iterator i = std::lower_bound(vvv.begin(), vvv.end(), column[ii],TokenCompare()); // 在次通過lower_bound查找,
        vvv.insert(i,column[ii]);
    }
    std::vector<COLUMN_DESC>::iterator itr ;
    for ( itr=vvv.begin() ; itr != vvv.end(); ++itr)
    {
        std::cout << itr->Token << "\t" << itr->Comment << "\t" << itr->value << std::endl;
    }
    return 0;
}


RESULT:
0000 dfdfdfdfdf 1
aaaa aaaaaaaa 13
abcd abcdabcd 1
aeecd eee2cdeeecd 3
aeecd eee1cdeeecd 5
aeecd eeecdeeecd 7
efef efefefefefef 11
sdfg sdfsdfsdf 9



int main(int argc, char* argv[])
{
    COLUMN_DESC key[]={
     { "aeecd","eeecde2eecd" ,3},
    };
    COLUMN_DESC column[]={
     { "sdfg" , "sdfsdfsdf" , 9},
     { "abcd","abcdabcd" ,1},
     { "aeecd","eeecdeeecd" ,3},
     { "aeecd","eee1cdeeecd" ,5},
     { "aeecd","eee2cdeeecd" ,7},
     { "aaaa","aaaaaaaa" ,13},
     { "efef","efefefefefef" ,11},
     { "0000","dfdfdfdfdf" ,1},
    };
    std::vector<COLUMN_DESC> vvv;
    unsigned int colsz = (sizeof(column) / sizeof(column[0]));
    for ( int ii = 0 ; ii < colsz ; ii++)
    {
        std::vector<COLUMN_DESC>::iterator i = std::lower_bound(vvv.begin(), vvv.end(), column[ii],TokenCompare()); // 在次通過lower_bound查找,
        if(i != vvv.end() && !strcmp(i->Token ,column[ii].Token))
        {
            continue;
        }
        vvv.insert(i,column[ii]);
    }
    std::vector<COLUMN_DESC>::iterator itr ;
    for ( itr=vvv.begin() ; itr != vvv.end(); ++itr)
    {
         std::cout << itr->Token << "\t" << itr->Comment << "\t" << itr->value << std::endl;
    }
    std::vector<COLUMN_DESC>::iterator itr_v;
    itr_v = std::lower_bound(vvv.begin(), vvv.end(),key[0], TokenCompare());
    if(itr_v != vvv.end())
    {
         std::cout << "Found:\t"<< itr_v->Token << "\t" << itr_v->Comment << "\t" << itr_v->value << std::endl;
    }
    return 0;
}

0000 dfdfdfdfdf 1
aaaa aaaaaaaa 13
abcd abcdabcd 1
aeecd eeecdeeecd 3
efef efefefefefef 11
sdfg sdfsdfsdf 9
Found: aeecd eeecdeeecd 3



int main(int argc, char* argv[])
{
    COLUMN_DESC key[]={
     { "aeecd","eeecde2eecd" ,3},
    };
    COLUMN_DESC column[]={
     { "sdfg" , "sdfsdfsdf" , 9},
     { "abcd","abcdabcd" ,1},
     { "aeecd","eeecdeeecd" ,3},
     { "aeecd","eeecdeeecd" ,5},
     { "aeecd","1eeecdeeecd" ,7},
     { "aaaa","aaaaaaaa" ,13},
     { "efef","efefefefefef" ,11},
     { "0000","dfdfdfdfdf" ,1},
    };
    std::vector<COLUMN_DESC> vvv;
    unsigned int colsz = (sizeof(column) / sizeof(column[0]));
    for ( int ii = 0 ; ii < colsz ; ii++)
    {
        std::vector<COLUMN_DESC>::iterator i = std::upper_bound(vvv.begin(), vvv.end(), column[ii],TokenCompare()); // 在次通過lower_bound查找,
//        if(i != vvv.end() && !strcmp(i->Token ,column[ii].Token))
//        {
//            continue;
//        }
        vvv.insert(i,column[ii]);
    }
    std::vector<COLUMN_DESC>::iterator itr ;
    for ( itr=vvv.begin() ; itr != vvv.end(); ++itr)
    {
         std::cout << itr->Token << "\t" << itr->Comment << "\t" << itr->value << std::endl;
    }
    std::vector<COLUMN_DESC>::iterator itr_v;
    itr_v = std::upper_bound(vvv.begin(), vvv.end(),key[0], TokenCompare());
    if(itr_v != vvv.end())
    {
         std::cout << "Found:\t"<< itr_v->Token << "\t" << itr_v->Comment << "\t" << itr_v->value << std::endl;
    }
    return 0;
}

0000 dfdfdfdfdf 1
aaaa aaaaaaaa 13
abcd abcdabcd 1
aeecd eeecdeeecd 3
aeecd eee1cdeeecd 5
aeecd eee2cdeeecd 7
efef efefefefefef 11
sdfg sdfsdfsdf 9
Found: efef efefefefefef 11



int main(int argc, char* argv[])
{
    COLUMN_DESC key[]={
     { "aeecd","eeecde2eecd" ,3},
    };
    COLUMN_DESC column[]={
     { "sdfg" , "sdfsdfsdf" , 9},
     { "abcd","abcdabcd" ,1},
     { "aeecd","eeecdeeecd" ,3},
     { "aeecd","eee1cdeeecd" ,5},
     { "aeecd","eee2cdeeecd" ,7},
     { "aaaa","aaaaaaaa" ,13},
     { "efef","efefefefefef" ,11},
     { "0000","dfdfdfdfdf" ,1},
    };
    std::vector<COLUMN_DESC> vvv;
    unsigned int colsz = (sizeof(column) / sizeof(column[0]));
    for ( int ii = 0 ; ii < colsz ; ii++)
    {
        std::vector<COLUMN_DESC>::iterator i = std::upper_bound(vvv.begin(), vvv.end(), column[ii],TokenCompare()); // 在次通過lower_bound查找,
//        if(i != vvv.end() && !strcmp(i->Token ,column[ii].Token))
//        {
//            continue;
//        }
        vvv.insert(i,column[ii]);
    }
    std::vector<COLUMN_DESC>::iterator itr ;
    for ( itr=vvv.begin() ; itr != vvv.end(); ++itr)
    {
         std::cout << itr->Token << "\t" << itr->Comment << "\t" << itr->value << std::endl;
    }
    std::vector<COLUMN_DESC>::iterator itr_v;

    itr_v = std::upper_bound(vvv.begin(), vvv.end(),key[0], TokenCompare());
    if(itr_v != vvv.end())
    {
         std::cout << "Found:\t"<< itr_v->Token << "\t" << itr_v->Comment << "\t" << itr_v->value << std::endl;
    }
    pair < vector < COLUMN_DESC > ::iterator, vector < COLUMN_DESC > ::iterator > range = std::equal_range(vvv.begin(), vvv.end(),key[0],TokenCompare());
    std::cout << "Found_1:\t"<< range.first->Token << "\t" << range.first->Comment << "\t" << range.first->value << std::endl;
    std::cout << "Found_2:\t"<< range.second->Token << "\t" << range.second->Comment << "\t" << range.second->value << std::endl;
    return 0;
}

0000 dfdfdfdfdf 1
aaaa aaaaaaaa 13
abcd abcdabcd 1
aeecd eeecdeeecd 3
aeecd eee1cdeeecd 5
aeecd eee2cdeeecd 7
efef efefefefefef 11
sdfg sdfsdfsdf 9
Found: efef efefefefefef 11
Found_1: aeecd eeecdeeecd 3
Found_2: efef efefefefefef 11

2013年1月15日 星期二

auto_ptr and smart_ptr




//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <memory>
#include <string>
#include <iostream>
//---------------------------------------------------------------------------
class A
{
        std::string m_strAAA;
public:
        A():m_strAAA(""),x(0){std::cout <<"A:" << m_strAAA << std::endl;}
        A(const A &a):m_strAAA(a.m_strAAA),x(a.x){std::cout <<"A2:" << m_strAAA << std::endl;}
        A(const std::string &str):m_strAAA(str),x(0){std::cout <<"A3:" << m_strAAA << std::endl;}
        void print(){std::cout <<"[" << m_strAAA << "]"<< std::endl;}
        ~A(){std::cout <<"~A:" << m_strAAA << std::endl;}
        const std::string & GetAAA(){return m_strAAA;}
        int x;
};

class RC
{
    private:
    int count; // Reference count

    public:
    RC():count(0){}   // <-- initialize counter
    void AddRef()
    {
        // Increment the reference count
std::cout << "add_ref" << std::endl;
        count++;
    }

    int Release()
    {
std::cout << "release" << std::endl;
        // Decrement the reference count and
        // return the reference count.
        return --count;
    }
};
template < typename T > class SP
{
private:
    T*    pData;       // pointer
    RC* reference; // Reference count

public:
    SP() : pData(0), reference(0)
    {
        // Create a new reference
        reference = new RC();
        // Increment the reference count
        reference->AddRef();
    }

    SP(T* pValue) : pData(pValue), reference(0)
    {
        // Create a new reference
        reference = new RC();
        // Increment the reference count
        reference->AddRef();
    }

    SP(const SP<T>& sp) : pData(sp.pData), reference(sp.reference)
    {
        // Copy constructor
        // Copy the data and reference pointer
        // and increment the reference count
        reference->AddRef();
    }

    ~SP()
    {
std::cout << "content will be destructed!! [" << pData->GetAAA() << "]" << std::endl;
        // Destructor
        // Decrement the reference count
        // if reference become zero delete the data
        if(reference->Release() == 0)
        {
            delete pData;
            delete reference;
        }
    }

    T& operator* ()
    {
        return *pData;
    }

    T* operator-> ()
    {
        return pData;
    }
    
    SP<T>& operator = (const SP<T>& sp)
    {
        // Assignment operator
        if (this != &sp) // Avoid self assignment
        {
            // Decrement the old reference count
            // if reference become zero delete the old data
            if(reference->Release() == 0)
            {
                delete pData;
                delete reference;
            }

            // Copy the data and reference pointer
            // and increment the reference count
            pData = sp.pData;
            reference = sp.reference;
            reference->AddRef();
        }
        return *this;
    }
};
int main(int argc, char* argv[])
{
/*test auto_prt*/
        std::auto_ptr<A> aa;
        A a;
        {
        std::auto_ptr<A> aa1(new A("aa1"));
        aa1->print();
        aa=aa1;
        if(aa1.get()==0)
                std::cout << "aa1 ptr transfer to aa !!" << std::endl;
        }

        {
        std::auto_ptr<A> aa2(new A("aa2"));
        aa2->print();
        if(aa2.get()==0)
                std::cout << "aa2 ptr transfer to aa !!" << std::endl;
        }


/*test smart pointer*/
    SP<A> p(new A("Scott"));
    p->print();
    {
        SP<A> q = p;
        q->print();

        SP<A> r;
        r = p;
        r->print();
        
        // Destructor of q will be called here..
        // Destructor of r will be called here..
    }
    p->print();


    // Destructor of p will be called here 
    // and A pointer will be deleted



        return 0;
}
//---------------------------------------------------------------------------

結果顯示
/*test auto_prt*/
A:
A3:aa1
[aa1]
aa1 ptr transfer to aa !!
A3:aa2
[aa2]
~A:aa2

/*test smart pointer*/
A3:Scott
add_ref
[Scott]
add_ref
[Scott]
add_ref
release
add_ref
[Scott]
content will be destructed!! [Scott]  --> q
release
content will be destructed!! [Scott]  --> r
release
[Scott]
content will be destructed!! [Scott]  --> p

/* after return 0; */
release
~A:Scott
~A:
~A:aa1



reference: http://www.codeproject.com/Articles/15351/Implementing-a-simple-smart-pointer-in-c
http://caterpillar.onlyfun.net/Gossip/CppGossip/autoPtr.html


文章分類