functor #


functor(함수객체)는 함수의 인터페이스를 지원하는 객체를 말합니다.
구체적으로 말하면 class에 operator()를 overloading하여 사용하는
관용구를 말합니다.

#include <iostream>
#include <string>
using namespace std;


class Adder
{
public:
  Adder() {}
  ~Adder() {}

  int operator()(int lvalue, int rvalue)
  {
    return nSum_ = (lvalue + rvalue);
  }

  int operator()(int value)
  {
    return nSum_ += value;
  }

  int Result() const
  {
    return nSum_;
  }

private:
  int nSum_;

};


int FnAdd(int lvalue, int rvalue)
{
  return lvalue + rvalue;
}


int main()
{
  Adder add;

  cout << add(3, 6) << endl;
  cout << FnAdd(2, 4) << endl;

  cout << add(1) << endl;
  cout << add.Result() << endl;
}

위의 코드는 함수와 함수객체와의 단적인 확장성을 볼수 있습니다.

Adder객체는 함수 FnAdd와 인터페이스는 같으면서 두수를 더하고 그 결과를 리턴과
동시에 저장을 할수 있으며 그 결과값으로 다시 연산을 할수 있는
확장성을 보여줍니다.

예에서 볼수 있듯이 함수객체는 객체에 함수인터페이스를 추가함으로서
함수 호출 부분에 대신 들어가 더욱더 확장성 있는 일을 해낼수가 있습니다.


그리고 함수포인터로는 불가능한 inlining 작업을 수행함으로서 성능향상을
꽤할수도 있습니다.


#include <iostream>
#include <string>
using namespace std;


class Printer
{
public:
  Printer() {}
  ~Printer() {}

  template <class T>
  void operator()(const T &ty)
  {
    cout << ty << "!";
  }
};

void Print(int n)
{
  cout << n << ":";
}


template <class IterT, class FunT>
void ForEach(IterT begin, IterT end, FunT fun)
{
  while (begin != end) {
    fun(*begin++);
  }
}


int main()
{
  enum { ARR_SIZE = 5 };
  int nArr[ARR_SIZE] = { 1, 2, 3, 4, 5 };

  Printer printer;
  ForEach(nArr, nArr + ARR_SIZE, printer);
  cout << endl;

  ForEach(nArr, nArr + ARR_SIZE, Print);
  cout << endl;

  cin.get();
}

위의 Printer객체의 인스턴스인 printer는 void operator()(const T &ty) 가
인라인으로 되어 있어 ForEach 함수안에서 함수의 오버헤드 없이 호출이 되지만
Print함수는 앞에 inline키워드를 붙여 인라인을 강제하여도 함수포인터를 호출하려면
함수의 주소가 필요한 규칙에의해 컴파일러에게 인라인이 무시가 됩니다.


물론 인라인의 무절제한 사용으로 인한 성능 저하를 배제한다면 ...

'Dev > C++' 카테고리의 다른 글

explicit  (0) 2008.05.01
template  (0) 2008.05.01
Casting operators  (0) 2008.05.01
export  (0) 2008.05.01
main function  (0) 2008.05.01

Casting operators #

C++에서는 4가지의 cast 연산자가 추가 되었습다.
물론 C언어와의 호환성을 위해 C언어의 문법도 지원합니다.
그러나 명확하고 보다 안전함 때문에 C++의 cast를 추천합니다.


static_cast #

사전적 의미는 런타임시 타입에 대한 체크와 cast가 이루어지는것이 아니고
컴파일시에 체크와 cast되는 연산자

일반적으로 C언어의 형변환이 여기에 속합니다.
그리고 base 클래스에서 derived 클래스로의 down cast시에도 이용되는데
런타임시 타입을 체크하지 않고 cast가 되기 때문에 오버헤드는 없으나
잘못된 포인터로 인한 위험은 존재합니다.
class Base {};
class Derived : public Base {};

void f(Derived *p)
{
}

int main()
{
  Base *p = new Derived;
  f(static_cast<Derived *p>(p)); // down cast 

  int i = 39;
  unsigned long lvalue = static_cast<unsigned long>(i); // 일반적인 cast 
  unsinged long lvalue2 = (unsigned long)i;  // C언어 cast도 지원 
}


reinterpret_cast #

다른 타입간의 형변환에 사용됩니다.
일반적으로 일반타입과 포인터간 혹은 서로 다른 타입의 포인터간 cast에 사용됩니다.
int main()
{
  int n = 90;
  char *p = reinterpret_cast<char *>(&n);  // 서로다른 포인터 

  int nHandle = reinterpret_cast<int>(p);  // 포인터와 일반타입 
}


const_cast #

const, volatile 두개의 키워드로 선언된 변수의 속성을 제거하는 cast 입니다.
const_cast는 상수성및 휘발성의 성질을 제거할때만 사용되고 다른 현변환이나
클래스계층간 cast할수는 없습니다.
int main()
{
  const char sz[] = "TEST";
  char *p = const_cast<char *>(sz);
}


dynamic_cast #

static_cast와 상대적인 의미의 cast로서 클래스의 안전한 downcast에 이용됩니다.
dynamic_cast는 컴파일시 타입을 체크하는것이 아니고 런타임시 포인터의 타입이 아닌
실제로 가르키고있는 객체의 계층간 타입을 확인해 cast를 해주는 연산자이고
그로인해 약간의 오버헤드가 존재 합니다.

dynamic_cast의 기본개념은 virtual function table에 있는 들어있는 타입의 정보를
이용하기 때문에 virtual member function을 가지고 있는
Base클래스에서 상속받은 객체로의 cast만 가능합니다.

그리고 오버헤드로 인하여 몇몇 컴파일러들은 기본으로 이 기능을 끄고 사용할때 옵션으로서
기능을 켜고 사용할수 있게 제공됩니다
(대표적으로 VC++이 여기에 속합니다. VC++에서 dynamic_cast를 이용하려면
Project 세팅에서 옵션을 체크해줘야 됩니다.)

dynamic_cast의 행동은
포인터는 cast가 성공일 경우 해당 포인터를 cast가 실패일 경우 NULL로 세팅을 합니다.
참조의 경우는 cast가 실패하면 bad_cast Exception 이 발생합니다.
class NotVBase
{
public:
  ~NotVBase() {}
};
class NotVDerived : public NotVBase {};

class VBase
{
public:
  virtual ~VBase() {}
};
class VDerived : public VBase{};

int main()
{
  NotVBase *p = new NotVDerived;
  // ERROR   
  // 컴파일러에서 에러를 잡아 줄것 입니다. 
  // Base 클래스가 virtual member 가 존재하지 않습니다. 
  NotVDerived *pp = dynamic_cast<NotVDerived *>(p);   // 컴파일 에러   


  VBase *vp = new VDerived;
  VBase *nvp = new VBase;

  VDerived *vpp1 = dynamic_cast<VDerived *>(vp); // SUCCESS   

  // nvp가 가르키고 있는 포인터는 VDerived 타입이 아닙니다. 
  // 따라서 vpp 에는 NULL이 세팅됩니다.   
  VDerived *vpp2 = dynamic_cast<VDerived *>(nvp);
  if (!vpp2) {
    // 이부분이 실행됩니다.   
  }

  try {
    // 만약 참조로 cast하다 실패하면 bad_cast Exception이 발생합니다. 
    VDerived &vd = dynamic_cast<VDerived &>(*nvp);
  }
  catch (...) {}

}

dynamic_cast는 계층간의 downcast는 물론
다중상속으로 인한 Base 클래스끼리의 형변환도 해당이 됩니다.

class Base1
{
public:
  virtual ~Base1() {}
};

class Base2
{
public:
  virtual ~Base2() {}
};

class Derived : public Base1, public Base2
{

};

int main()
{
  Base1 *p1 = new Derived();

  // Base1 에서 Base2로의 형변환 
  // p1이 가르키고 있는 타입은 Derived 
  Base2 *p2 = dynamic_cast<Base2 *>(p1); // SUCCESS 

}

'Dev > C++' 카테고리의 다른 글

template  (0) 2008.05.01
functor - 함수객체  (0) 2008.05.01
export  (0) 2008.05.01
main function  (0) 2008.05.01
tr1::regex (boost::regex) 샘플코드  (0) 2007.10.21

export #

C++ template의 내보내기 키워드 입니다.
아직 제대로 구현되어 있는 컴파일러는 없습니다.


template은 타입이 정의 되지 않은 상태의 함수나 객체를 컴파일 타입에 정의를해서 코드를 생성하는 일종의 코드제너레이터 같은 것입니다.
template <class T>
class TClass
{
  T t;
};

위의 코드는 TClass<int> intClass 란 식으로 인스턴스를 만들기 전까지는 혹은 함수 같은 경우 사용되지 전까지는 코드를 만들지 않습니다.

아마 아래와 같은 코드를 컴파일 당시 만들것입니다.

class TClass
{
  int t;
};

그도 그럴것이 타입을 모르는데 어떻게 코드를 만들겠습니까?
그렇다고 모든 타입에 대해서(사용자정의 타입까지 한다면 헉..)다 코드를 만들수는 없는 노릇이고 ...

Object 파일 #

Object 파일 즉 중간 파일은 바이너리 코드 입니다.
컴파일된 기계코드이지요
이미 그안에는 실행되어지는 내용들이 있습니다.

그런데 template으로 라이브러리를 만들어서 Object 파일을 만든다면 ...
과연 타입이 없는데 어떤식으로 코드를 생성해서 놓을까여 ????

export는 그 답을 주는 키워드 입니다.
export는 template 내용을 Object파일에 넣어서 재사용 할수 있도록 하는 도구 입니다.

그러나 위에서 말한것 처럼 구현하기가 쉬운일은 아닌거 같습니다.
많은 비용도 들고 ...
이런 이유에서 컴파일러사 마다 쉽게 구현 못하는 이유일꺼라고 생각합니다.

아직 VC++이나 Borland C++, GNC C++ 의 대표적인 컴파일러 회사들의 구현물들도 아직 그것을 구현하지 못하고 있습니다.

아래의 링크 밑에 부분에 "export 및 내보낸 템플릿" 이란 주제로 Bobby Schmidt이란 사람이 글을 써놓은것이 있습니다.
한마디로 끔찍하다는 표현을 -_-

'Dev > C++' 카테고리의 다른 글

functor - 함수객체  (0) 2008.05.01
Casting operators  (0) 2008.05.01
main function  (0) 2008.05.01
tr1::regex (boost::regex) 샘플코드  (0) 2007.10.21
boost 를 이용한 TR1 Library 사용하기  (0) 2007.10.10

main Function #

ISO C++의 공식 main함수의 원형은 아래와 같습니다.

int main()
int main(int argc, char *argv[])

두개의 원형이 아닌이상 모두 표준에 어긋나는것입니다.
표준화이전에 쓰여진 책 혹은 컴파일러에서는 void main() 이란 원형도 타탕하다는 주장이 있었습니다.
그러나 그것은 표준에 어긋납니다.
VC++ 같은 컴파일러는 void main()을 허용하지만 하위호환성을 위해 남겨 놓은 것 뿐입니다.


return #

표준 main함수는 int를 리턴하게 되어 있습니다.
int main()
{
  return 0;
}

허나 ISO C++에서는 main함수에서의 명시적인 리턴이 없으면 자동으로 return 0;를 자동으로 넣어줍니다.

// 이 main은 타당합니다. 
// 컴파일러에 의해 return 0; 가 수행됩니다. 
int main()
{
}

'Dev > C++' 카테고리의 다른 글

Casting operators  (0) 2008.05.01
export  (0) 2008.05.01
tr1::regex (boost::regex) 샘플코드  (0) 2007.10.21
boost 를 이용한 TR1 Library 사용하기  (0) 2007.10.10
VC++ 2005 배포  (0) 2007.06.22

#include <iostream>
#include <string>
#include <memory>
#include <fstream>
#include <iterator>
#include <sstream>
#include <vector>
#include <functional>
#include <regex>
using namespace std;


typedef vector<string> MatchList;
typedef MatchList::iterator MatchListIter;


bool MatchFunc(const boost::smatch &m, MatchList *p)
{
    p->push_back(m.str());
    return true;
}


void RegExTest(const char *pFileName)
{
    ifstream fin(pFileName);
    if (!fin) {
        cout << "file open error !!" << endl;
        return;
    }


    ostringstream oss;
    copy(istreambuf_iterator<char>(fin), istreambuf_iterator<char>(), ostreambuf_iterator<char>(oss));


    tr1::regex expr;
    expr.assign("<[a-zA-Z\\s\\/][^>]*>");    // html 표현식

   
    // replace 매치되는 문자열 치환
    string strResult = boost::regex_replace(oss.str(), expr, "");

    MatchList mlist;


    // grep 매치되는 문자열 찾기
    int nMatch = boost::regex_grep(tr1::bind(MatchFunc, _1, &mlist), oss.str(), expr);

    MatchListIter it = mlist.begin();
   
    for (; it != mlist.end(); ++it) {
        cout << *it << endl;
    }
}

'Dev > C++' 카테고리의 다른 글

export  (0) 2008.05.01
main function  (0) 2008.05.01
boost 를 이용한 TR1 Library 사용하기  (0) 2007.10.10
VC++ 2005 배포  (0) 2007.06.22
Unhandled C++ Exceptions  (0) 2007.06.19

출처 : http://boost.org/doc/html/boost_tr1/usage.html

boost 1.34 버전 이상 부터 지원

std::tr1 내용 :

Reference Wrappers.
Smart Pointers.
Class template result_of.
Function template mem_fn.
Function Object Binders.
Polymorphic function wrappers.
Type Traits.
Random Number Generators and Distributions.
Tuples.
Tuple Interface to std::pair.
Fixed Size Array.
Hash Function Objects.
Regular Expressions.
Complex Number Algorithm Overloads.
Complex Number Additional Algorithms.




Header Include Style

There are two ways you can include the Boost.TR1 headers, for example if you are interested in shared_ptr then you can either use:

#include <boost/tr1/memory.hpp>

or:

#include <memory>

The first option is the preferred method for other Boost libraries to use. The second option is standard-conforming, but requires that you add boost-install-path/boost/tr1/tr1 to your compiler's include search path. Note that you must not copy the headers in boost/tr1/tr1 into a directory called "include", doing so will cause them to cease working.


Important Note #1


The include path order is very important if you want this library to work correctly. If you get compiler errors then suspect the include paths. The correct order is:

1) boost-root/boost/tr1/tr1
2) boost-root
3) Any other standard library replacements (STLport for example).
4) Your regular standard library.

Important Note #2: Borland C++ Users


Borland's compiler has a particularly broken form of #include, that will actually look for a file named array.h if you #include <array>. In order to make this library work with Borland's compiler you will need to set up the include paths as follows:

1) boost-root/boost/tr1/tr1/bcc32
2) boost-root/boost/tr1/tr1
3) boost-root
4) Any other standard library replacements (STLport for example).
5) Your regular standard library.

Important Note #3: Sun C++ Users

Sun's compiler has a particularly interesting form of #include, that will actually look for a file named array.SUNWCCh if you #include <array>. In order to make this library work with Sun's compiler you will need to set up the include paths as follows:

1) boost-root/boost/tr1/tr1/sun
2) boost-root/boost/tr1/tr1
3) boost-root
4) Any other standard library replacements (STLport for example).
5) Your regular standard library.

'Dev > C++' 카테고리의 다른 글

main function  (0) 2008.05.01
tr1::regex (boost::regex) 샘플코드  (0) 2007.10.21
VC++ 2005 배포  (0) 2007.06.22
Unhandled C++ Exceptions  (0) 2007.06.19
OutputDebugString  (0) 2007.05.23

'Dev > C++' 카테고리의 다른 글

tr1::regex (boost::regex) 샘플코드  (0) 2007.10.21
boost 를 이용한 TR1 Library 사용하기  (0) 2007.10.10
Unhandled C++ Exceptions  (0) 2007.06.19
OutputDebugString  (0) 2007.05.23
C++0x  (0) 2007.05.16
#include <iostream>
using namespace std;
void term_func()
{ cout << "term_func was called by terminate." << endl; exit( -1 ); }
int main()
{ try { set_terminate( term_func ); throw "Out of memory!"; // No catch handler for this exception } catch( int ) { cout << "Integer exception raised." << endl; }
return 0; }

'Dev > C++' 카테고리의 다른 글

boost 를 이용한 TR1 Library 사용하기  (0) 2007.10.10
VC++ 2005 배포  (0) 2007.06.22
OutputDebugString  (0) 2007.05.23
C++0x  (0) 2007.05.16
GRETA  (0) 2007.05.14


// printf 포맷을 이용하는 OutputDebugString 함수
void Trace(LPCTSTR szFormat, ...)
{
    enum { BUFF_SIZE = 2048 };

    TCHAR szTempBuf[BUFF_SIZE] ;
    va_list vlMarker ;

    va_start(vlMarker,szFormat) ;
    _vstprintf(szTempBuf,szFormat,vlMarker) ;
    va_end(vlMarker) ;

    OutputDebugString(szTempBuf) ;
}

'Dev > C++' 카테고리의 다른 글

VC++ 2005 배포  (0) 2007.06.22
Unhandled C++ Exceptions  (0) 2007.06.19
C++0x  (0) 2007.05.16
GRETA  (0) 2007.05.14
A non-type template-parameter  (0) 2007.05.14

'Dev > C++' 카테고리의 다른 글

Unhandled C++ Exceptions  (0) 2007.06.19
OutputDebugString  (0) 2007.05.23
GRETA  (0) 2007.05.14
A non-type template-parameter  (0) 2007.05.14
Member template specialization  (0) 2007.05.14
MS의 research site에서 다운 받을수 있는 정규식(Regular Expression ) 라이브러리 이다.

C++에서도 펄과 같은 정규식표현식이 필요할때 사용을 하면 된다.
물론 이것 말고 더 boost의 regex++ 라는 유명한 라이브러리도 있지만 regex++보다 가볍고 몇개의 소스로 배포 되어 있어서 사용하기에 더 편한것 같다.
그리고 regex++보다 낳은 성능을 주장(?)하고 있다

그렇지만 현재 적용중인 몇개의 소스는 regex++ 로 되어 있다


The GRETA Regular Expression Template Archive

  • Fast backtracking regular expression engine.
  • Separately compiled patterns.
  • Matches against C-style NULL-terminated strings, C++-sytle std::string's, or iterator ranges.
  • Template on iterator type and syntax module.
  • Supports Unicode.
  • Syntax is encapsulated in easily customized/replaced modules. (Perl and POSIX syntax modules included.)
  • Match balanced, nested tags with a recursive pattern. Great for HTML/XML/SOAP processing.
  • Many times faster than the .NET/ATL7 regex classes.
  • Consistently outperforms than boost regex++ on short strings; performs competitively on long strongs (see this page for a detailed comparison).

  • 'Dev > C++' 카테고리의 다른 글

    OutputDebugString  (0) 2007.05.23
    C++0x  (0) 2007.05.16
    A non-type template-parameter  (0) 2007.05.14
    Member template specialization  (0) 2007.05.14
    A member template cannot be virtual  (0) 2007.05.14
    14.1.4
    A non-type template-parameter shall have one of the following (optionally cv-qualified) types:

    * integral or enumeration type,
    * pointer to object or pointer to function,
    * reference to object or reference to function,
    * pointer to member.

    [Programming Language C++ (ISO)]

    'Dev > C++' 카테고리의 다른 글

    C++0x  (0) 2007.05.16
    GRETA  (0) 2007.05.14
    Member template specialization  (0) 2007.05.14
    A member template cannot be virtual  (0) 2007.05.14
    sgi STL - Why does Bounds Checker™ say that I have memory leaks?  (0) 2007.05.14

    + Recent posts