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

文章分類