ChangeLog 最新ページ / カテゴリ最新ページ / 1 2 3 次ページ / page 1 (3)

cxx - ~matubara/ChangeLog移動しました

最終更新時間: 2009-02-01 00:57

2007-12-26 Wed

boost::regex [cxx][programming]

boost::regex は Perl みたいな感じで正規表現を使わせてくれるライブラリ。

#include <iostream>
#include <boost/regex.hpp>

int main() {
  using namespace std;
  using boost::regex;
  using boost::sregex_token_iterator;
  string s("a/b c/d e/f");
  sregex_token_iterator
    i(s.begin(), s.end(), regex("\\s"), -1),
    end;
  for ( ; i != end; ++i ) {
    string w(i->first, i->second);
    cout << w << endl;
    sregex_token_iterator
      j(w.begin(), w.end(), regex("/"), -1);
    for ( ; j != end; ++j ) {
      cout << string(j->first, j->second) << endl;
    }
  }
}
wregex, wsregex_token_iterator を使うと、とりあえず多バイト文字が扱える。

u32regex, u32regex_token_iterator を使うと、Unicode の文字クラスが使える(ICU必要)。
http://www.boost.org/libs/regex/doc/icu_strings.html

2007-12-21 Fri

N-gram Template Library [cxx][nlp]

<http://karlmicha.googlepages.com/lg>
作ってたのとほとんど同じものがあった。

2007-11-25 Sun

C++におけるユニコード文字列は std::wstring で [programming][cxx]

C++でユニコード文字といえば
ICU4C
があるけれど、
・APIが非常にJava的なので、あまり使いたくない(STLと相性が悪い)
・正規化処理等を含んでいるので、単に格納して単なる文字列と同じように使いだけの場合にはオーバースペック
などという問題がある。

そこで vector<short> とか考えたけれど、
入出力とかソートとかそれはそれで用意しなければならない。
Javaと違って、統一interfaceをimplementsしてそれを満たせば終わりというわけじゃないので、
面倒。

実は2バイト文字が格納できて入出力もサポートされていて、
かつSTLに対応済(というかSTLの中にある)の
std::wstring
がある。

std::wstring は言語仕様上、単に、
1文字が8ビットより大きいバージョンの std::string
としか定義されていない。
文字長とか文字集合とか、エンコーディングとか、ソート順序とかは全部処理系依存。
この辺が原因で、ポータビリティがないとされている。
(2007-12-18T22:41:39+0900) : 実際、文字コードの指定方法(名前)に関して、Linux同士でも互換性がない。また、複数のエンコーディングを扱うのも苦手。

その辺はあくまで言語仕様の話で、存在する実装では
windows と linux で、wstring = UTF-16文字列
ソートはUTF-16の辞書式らしい。(要出典)
linux では UTF-16 を 32ビットのintに入れて格納しているので、メモリはかなり食う。
wstring の作成は
・処理系がlocaleを持っている
・ソースコードが locale のエンコーディングで書かれている
・扱うデータが locale のエンコーディングで書かれているものだけ
という前提だったら、

std::wstring s;
std::wcin >> s;

という感じでやれる。
このとき、cinを混在させるとなんかややこしいことになった気がするので注意。

2007-11-24 Sat

均等分割 [cxx]

最初を適当に決めて、残りを再帰で均等に。
頭の悪いアルゴリズムなので、計算量とかスタックとかがいろいろ大変なことになっている。

#include <iostream>
#include <list>
#include <iterator>
#include <locale>
#include <cassert>

using namespace std;

pair<list<wstring>,size_t> divid_len(size_t num, const wchar_t* str, size_t len) {
  if ( num == 1 ) {
    for ( ; ; ++len ) {
      if ( *(str+len) == L'\0' ) {
        list<wstring> l;
        l.push_back(wstring(str,len));
        return make_pair(l, len);
      }
    }
  } else {
    for ( ; ; ++len ) {
      pair<list<wstring>, size_t> other = divid_len(num - 1, str + len, len);
      if ( abs(static_cast<long>(other.second - len)) <= 1 ) {
        list<wstring>& l = other.first;
        l.push_front(wstring(str,len));
        return make_pair(other.first, max(len, other.second));
      }
    }
    assert(false);
  }
}

list<wstring> divid(size_t size, const wchar_t* str) {
  return divid_len(size, str, 0).first;
}

int main() {
  locale::global(locale(""));
  const wchar_t* sample = L"ゆめよりもはかなき世のなかをなげきわびつゝあかしくらすほどに四月十よひにもなりぬれば木のしたくらがりもてゆく";
  list<wstring> ans;
  ans = divid(4, sample);
  copy(ans.begin(), ans.end(), ostream_iterator<wstring, wchar_t>(wcout, L"\n"));
  ans = divid(5, sample);
  copy(ans.begin(), ans.end(), ostream_iterator<wstring, wchar_t>(wcout, L"\n"));
  ans = divid(6, sample);
  copy(ans.begin(), ans.end(), ostream_iterator<wstring, wchar_t>(wcout, L"\n"));
  return 0;
}

2007-06-08 Fri

Casting does not work as expected when optimization is turned on. [cxx][net]

<http://gcc.gnu.org/bugs.html#nonbugs_c>

2007-05-08 Tue

Reference is not alias [cxx]

#include <iostream>

class cmplx {
public:
  double x;
  double y;
  double& real;
  double& imaginary;

public:
  cmplx(double _x, double _y) : x(_x), y(_y), real(_x), imaginary(_y) {}
};

int main(int argc, char** argv) {
  cmplx c(0.1, 0.1);
  std::cout << c.real << "+i" << c.imaginary << std::endl;
}

Following the discussion in http://www.thescripts.com/forum/thread640395.html,
I can say that making aliases for a member variable using reference is not a good idea.
Since, in run time, those aliases *may or may not* be deleted.

In the above example, the type cmplx may consume sizeof(double)*2 + sizeof(double*),
or sizeof(double)*2.

#include <iostream>

class cmplx_simple {
public:
  long double x;
  long double y;

public:
  cmplx_simple(long double _x, long double _y) : x(_x), y(_y) {}
};

class cmplx {
public:
  long double x;
  long double y;
  mutable long double& real;
  mutable long double& imaginary;

public:
  cmplx(long double _x, long double _y) : x(_x), y(_y), real(x), imaginary(y) {}
};

int main(int argc, char** argv) {

  cmplx_simple x(10.0, 10.0);
  cmplx c(0.1, 0.1);

  std::cout << sizeof(x) << std::endl;
  std::cout << sizeof(c) << std::endl;
  std::cout << c.real << "+i" << c.imaginary << std::endl;
  c.x = 0.2;
  c.y = 0.3;
  std::cout << c.real << "+i" << c.imaginary << std::endl;
  std::cout << &c.real << " " << &c.x << std::endl;
}

2007-05-04 Fri

コンストラクタのインターフェイスを増やす [cxx]

Javaでいうところの

public class Foo {
  public Foo(String s) {
  ...
  }
  public Foo(SomeClass x) {
    this(x.toString());
  }

がやりたいのですが、

class Foo {
  Foo(string s) {
  ...
  }
  Foo(int x) {
    Foo(x + "");
  }
}

だと

→ 共通部分を関数にしてください。
[10.3] How can I make a constructor call another constructor as a primitive? -- No way.

2007-02-16 Fri

vector で 2次元配列 [cxx]

#include <vector>
#include <iostream>
using namespace std;
int main() {
  vector<vector<double> > table(2, vector<double>(2));
  table[0][0] = 0.1;
  table[0][1] = 0.2;
  table[1][0] = 0.3;
  table[1][1] = 0.4;

  for ( vector<vector<double> >::iterator
  i = table.begin(),  e = table.end();
i != e; ++i ) {
    for ( vector<double>::iterator
    j = i->begin(), f = i->end();
  j != f; ++j ) {
      cout << *j << endl;
    }
  }
}

2007-02-09 Fri

バベル案内 [java][cxx][net]

<http://www.aoky.net/articles/steve_yegge/tour_de_babel.htm>

Javaに切り替えることは、2人のプログラマになることだ。
1人はあなたがもはや気にかけなくて良くなったことの面倒を見、もう1人が問題領域にフォーカスする。

2007-02-01 Thu

nesugi.net - swigの使い方のメモ書き [ruby][perl][cxx][net]

<http://www.nesugi.net/hiki/?swig%A4%CE%BB%C8%A4%A4%CA%FD%A4%CE%A5%E1%A5%E2%BD%F1%A4%AD>

   1. moduleにしたいプログラムのsource(*.cppとか)を持ってくる
   2. cppファイル毎に*.iを書く ← これがswig語
   3. swigコマンドで*.iを各スクリプト言語用のwrapper(c++で書かれてる)に変換
   4. Makefile.PLやextconf.rbのような、スクリプト言語用のMakefileの元になるファイルを書く
   5. 通常のモジュールと同じようにmakeする

2006-12-28 Thu

Java for C++ programmer [java][cxx]

関数ポインタはない。
→ interface 経由で”関数”を持つクラスのシングルトンインスタンスを渡す。

リンクはしなくていい。
ただし、ライブラリを使うプログラムを実行するときに、
ライブラリがある場所にパスを通す必要がある。
java -cp lib:. Main
→ 少なくとも、. は CLASSPATH に入れておくべき

ArrayList は add しないとサイズが増えない。
→ 自動的に fill されることがない

generics は template ではない。
Map<K,V> で、
K.equals の引数は Object です。
コンパイル時に型情報は消されます。
Map の契約は要素型に equals(Object) 、 hashCode(void) メソッドの妥当な実装を要求する。
→ annotation
@Override public boolean equals(Object o){ ... }

2006-12-18 Mon

Linkers and Loaders [cxx][programming][book][net]

<http://www.iecc.com/linker/>
リンカの本。

2006-11-07 Tue

Floating point arithmetic in C++ templates. [cxx][net]

<http://mi.eng.cam.ac.uk/~er258/code/fp_template.html>

2006-10-18 Wed

高階 template [cxx]

ふつうにできるのを知ってショックでした。
以前、それらしく書いてみたらコンパイルエラーだったので、
できないと思い込んでいた。

// パラメータとして型を渡す template class
template< typename T > class T0 {};

// パラメータとして1階テンプレートクラスを渡す template class
template< template<typename> class T > class T1 {};

// パラメータとして2階テンプレートクラスを渡す template class
template< template<template<typename> class> class T > class T2 {};

// パラメータとしてテンプレートと型を受け取り、テンプレート適用をする
template<template<typename> class TMPL, typename T> class ApplyTmpl {
public:
  typedef TMPL<T> type;
  type constructor() { return type(); }
  type* newInstance() { return new type(); }
};

// パラメータとして値を渡す関数
int f0(int x) { return 0; }

// パラメータとして1階関数を渡す関数
int f1(int (*x)(int)) { return 0; }

// パラメータとして2階関数を渡す関数
int f2(int (*x)(int (*)(int))) { return 0; }

// パラメータとして関数と値を受け取り、関数適用をする
int apply_func(int (*x)(int), int y) {
  return x(y);
}

2006-10-09 Mon

g++ -fstrict-aliasing [cxx][net]

<http://gcc.gnu.org/onlinedocs/gcc-4.0.3/gcc/Optimize-Options.html#index-fstrict_002daliasing-511>

int i = 10;
float f = *( (int*)&i );
は移植性が低いだけでなく、GCC4の最適化

-O2
-O1 -fstrict-aliasing -fschedule-insns

によって意味が変わる。

訂正版

union int_float {
	int   as_int;
	float as_float;
}
int_float x;
int i = 10;
x.as_int = i;
float f = x.as_float;	

g++ 4.x はデフォルトでこの問題を起こす最適化が有効になっている。
g++ 4.0.3 はそれにもかかわらず、警告を出さない。

対処:
1) g++3 を使う
2) g++ 4.1 以降でコンパイルして問題箇所を見つけ、修正する

2006-10-07 Sat

Qt 4.2 -- Qt Tutorial [cxx][net]

<http://doc.trolltech.com/4.2/tutorial.html>
一見 Java awt, swing と似ている。
SIGNAL & SLOT のイベント処理のところは違うけれど。

qmake -project
qmake
make

2006-10-06 Fri

2006-10-06 Fri

bitwise operators [cxx][net]

<http://www.icce.rug.nl/documents/cplusplus/cplusplus03.html#an208>

x = ~x;
x = compl x;


x = x ^ 0;
x = x xor 0;

2006-10-05 Thu

Chapter10.Boost.StaticAssert [cxx][net]

<http://boost.org/doc/html/boost_staticassert.html>
コンパイル時に、型変数の値チェックとかできる。
かなり便利かも。

#include <iterator>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>

template <class RandomAccessIterator >
RandomAccessIterator foo(RandomAccessIterator from, RandomAccessIterator to)
{
   // this template can only be used with
   // random access iterators...
   typedef typename std::iterator_traits< RandomAccessIterator >::iterator_category cat;
   BOOST_STATIC_ASSERT((boost::is_convertible<cat, const std::random_access_iterator_tag&>::value));
   //
   // detail goes here...
   return from;
}

2006-09-01 Fri

C++ で hashCode [cxx]

任意の型のハッシュ値を計算する枠組みは?

Java は Object.hashCode() があるので、
ユーザー定義のクラスでもそれにのっとればいい。

C++ では boost::hash<typename T> が凖・標準。
http://www.boost.org/doc/html/hash.html

via http://d.hatena.ne.jp/y-hamigaki/20060826

Powered by chalow
inserted by FC2 system