STL の next_permutation を呼び出すだけの、簡単なソースのつもりなんですが、ideone の gcc-4.3.4 だとコンパイルエラーになってします。
http://ideone.com/BFoZ2
手持ちの環境で、mingw32 と、Solaris10 に付いてくる gcc ではコンパイルできて、実行もできます。
何が悪いのか、教えてください。
コンパイル可能な gcc のバージョンは以下の通りです。
■mingw32
d>gcc --version
2.95.2
■gcc @Solaris10
% gcc --version
gcc (GCC) 3.4.3 (csl-sol210-3_4-branch+sol_rpath)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# ネタとか、クイズじゃなくて、本当に何が悪いのか分かりません
自分も良く分かってないのですが「typename」を入れるとコンパイルが通るようです。
typename vector<T>::const_iterator i = v.begin();
http://ideone.com/lvBDZ
ちなみに、以下の環境でも、ideone と同様のエラーになるようでした。
VC++ はコンパイルできました。
<参考情報>
■ テンプレートの中でほかのテンプレートクラスのメンバ型を使う方法: typename や template の別の用法について - akihiko’s tech note
http://d.hatena.ne.jp/aki-yam/20100612/1276357023
ちなみに、警告は、次の通り。
------ コンパイル開始 ------
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
hatena120202.cpp:
警告 W8027 hatena120202.cpp 9: whileを含む関数はインライン展開できない
警告 W8008 D:\PROGRAMING\BORLAND\BCC55\include\vector.h 213: 条件が常に真(関数 __init_aux<int *>(int *,int *,_RW_is_not_integer) )
警告 W8066 D:\PROGRAMING\BORLAND\BCC55\include\vector.h 214: 実行されないコード(関数 __init_aux<int *>(int *,int *,_RW_is_not_integer) )
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
------ コンパイル終了 ------
ぼくが c++ をよく使ってたのは、十年以上も前ですが、テンプレートがちょっと複雑になるとコンパイラがエラーを出して、妙な回避策をひねりだしたり、テンプレートかを諦めたりした経験があるので、こういう specifier (日本語だとなんて言うんだ?) が必要なのも理解できます。
でも、こんなの (typename) 昔からありましたっけ?
template<class T> class ... {
じゃなくて、
template<typename T> class ... {
という書き方ができるのも、今回初めて知りました。
まあ、T はプライマリな型も指定できるんだから、class よりは typename の方が適切だろうというのも分かります。
typename は、標準C++(ISO/IEC 14882:1998)で導入されたキーワードのようですね。
おおよそ2000年以降に出版された 標準C++ の本であれば、記述があるようです。
ちなみに、typename が使えるようになったのは以下のバージョンのコンパイラからのようです。
(g++ や Borland C++ での実装時期は、ちょっと分かりませんでした。)
1997年 VC++ 5.0
1999年 Sun C++ 5.0
<参考情報>
■ Visual C++ 4.2 と 5.0 の主な違い
http://msdn.microsoft.com/ja-jp/library/cc438771(VS.71).aspx
> C++ にさらに準拠するように、新しいキーワード bool、explicit、
> false、mutable、true、および typename が追加されました。
■ テンプレート (C++ 移行ガイド)
http://docs.oracle.com/cd/E19957-01/805-7888/z4000220f2bf0/index.html
> C++ 標準にはテンプレートに関する新しい規則がいくつか導入されています。
> そのため、既存のコードが標準から外れたものになってしまう可能性があります。
> 特に、新しいキーワード typename を使用しているコードがこれに該当します。
手持ちの gcc 2.95.2 で、typename をつけて試してみたら、きちんと解釈されました。
規格に新しく追加されたものを実装し始めの頃は、下位互換に気を使ってたけど、
そのうち、コンパイラの性能を優先するようになった、というところかな。
■ スレッド: [cppll:10073] gcc 3.2, 3.3 で "implicit typename" warning が発生していますでしょうか。
http://ml.tietew.jp/cppll/cppll/thread_articles/10073
gcc 2.95.2 … 暗黙の typename として解釈される
gcc 3.2~3.4? … 暗黙の typename は警告扱い
gcc 3.4以降? … typename が無い場合はエラーとする
という感じのようです。
また、VC++ は、typename キーワード周りは緩いということみたいです。
やはり、互換性の為でしょうか・・・
■ typenameが必要な理由 - Faith and Brave - C++で遊ぼう
http://d.hatena.ne.jp/faith_and_brave/20080129/1201597743
良いですね、これ。
読み返しちゃいました。
>>
gcc 3.3 の info の "Deprecated Features" に以下のように deprecated だ
と書いてあるので、いずれエラー扱いになるのではないでしょうか?
The implicit typename extension has been deprecated and will be
removed from g++ at some point. In some cases g++ determines that a
dependent type such as `TPL<T>::X' is a type without needing a
`typename' keyword, contrary to the standard.
<<
これなんですね。
「a-kuma3 は、typename キーワードを覚えた」