2010-3-15[月] watcom,dmcのテンプレート不具合

open watcom 1.9rc1 が出ている模様. が c++ 関係はあまり進展していないのか、 1.8よりちょっとは増えたようだけれどまだ未実装のSTL関係は多そうで (stable_sortなかったり)、 クラステンプレートのメンバー関数テンプレートをクラス外に書くのも まだ未サポートのよう.

template<typename T>
class Bar {
public:
    template<typename U> void test(T* t, U bgn, U end);
};

template<typename T>
template<typename U>    // この行.
void Bar<T>::test(T* dst, U start, U last) {
    while (start != last) *dst++ = *start++;
}

のBar<T>::testの2つ目のtemplateでシンタックスエラー.

template<typename T >
class Foo {
public:
    template<typename U> void test(T* t, U bgn, U end) {
        while (bgn != end) *t++ = *bgn++;
    }
};

のようにクラス内に書くのはok.

ついでに、上記は dmd(8.51) でもコンパイルエラー(startが未定義)になる。 こっちは、 テンプレートな引数の名前が Bar::test()宣言と定義で違うのが気に入らないらしい。 定義側の引数 start, last を bgn, end に修正すれば ok。 (テンプレートでない引数は名前が宣言と定義で違っても無問題)

別のコンパイラ(bcc 5.? だったか)でも、

template<typename CharT, class Traits>
class Foo {

のようにクラス定義してメンバー関数を外に

template<typename C, class T>
void Foo<C,T>::hoge(…) {

みたいにテンプレート引数名を変えていたら 某かの不具合がでた覚えがあり(名前を統一したらok)

汎用性を思うならば(古いコンパイラ気にするなら)、 クラステンプレートのメンバー(関数)は、 下手にクラス定義から分離せずに、内部に書いてしまうほうが 余計なバグに出会わずに済むのかも。 (分離する場合は名前を揃える... てか、ひょっとして普通揃えないとダメなのかな?)

(ごちゃごちゃする定義はクラス外部に追い出して、 クラス宣言は身軽にしておこう、 なんて考えてたらドツボにハマることもあった、と)