【c++ のソースがコンパイルできません ><】 


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.

# ネタとか、クイズじゃなくて、本当に何が悪いのか分かりません

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2012/02/02 03:35:47
  • 終了:2012/02/07 23:30:06

ベストアンサー

id:cx20 No.1

cx20回答回数606ベストアンサー獲得回数1072012/02/02 07:38:55

ポイント200pt

自分も良く分かってないのですが「typename」を入れるとコンパイルが通るようです。

typename vector<T>::const_iterator i = v.begin();

http://ideone.com/lvBDZ

ちなみに、以下の環境でも、ideone と同様のエラーになるようでした。

  • Cygwin / g++(4.5.3)
  • OSX / g++(4.2.1)
  • OSX / clang++(3.0)

VC++ はコンパイルできました。

<参考情報>
■ テンプレートの中でほかのテンプレートクラスのメンバ型を使う方法: typename や template の別の用法について - akihiko’s tech note
http://d.hatena.ne.jp/aki-yam/20100612/1276357023

id:a-kuma3

おー。

よく読めば,typename を使えばいいと分かる.
prog.cpp:8: note: say ‘typename std::vector::const_iterator’ if a type is meant

た、確かに。

何ですか、この typename って。初めて見ました。
gcc 拡張? それとも、ちゃんとした予約語?

2012/02/02 07:56:59
id:cx20

STL は勉強不足で、よく分かってないのですが、typename を付けるのが正しいっぽいです。VC++ だと typename 付けなくても型を解析してくれるようですけど。

■ テンプレートあれこれ (4) -- typename の役割
http://www.fides.dti.ne.jp/~oka-t/cpplab-template-4.html

ちなみに、Cygwin / g++ だと以下のメッセージでした。

test.cpp:8:9: error: need ‘typename’ before ‘std::vector<T>::const_iterator’ because ‘std::vector<T>’ is a dependent scope

2012/02/02 08:06:03
  • id:rsc96074
    bccでは、警告が出ましたが、動きました。(^_^;
    ちなみに、警告は、次の通り。
    ------ コンパイル開始 ------
    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
    ------ コンパイル終了 ------
  • id:a-kuma3
    ちょっと古い Working Draft だけど、ISO C++ Standard を読んで、typename が、規格で決められた予約語だということは理解しました。
    ぼくが c++ をよく使ってたのは、十年以上も前ですが、テンプレートがちょっと複雑になるとコンパイラがエラーを出して、妙な回避策をひねりだしたり、テンプレートかを諦めたりした経験があるので、こういう specifier (日本語だとなんて言うんだ?) が必要なのも理解できます。

    でも、こんなの (typename) 昔からありましたっけ?

    template<class T> class ... {

    じゃなくて、

    template<typename T> class ... {

    という書き方ができるのも、今回初めて知りました。
    まあ、T はプライマリな型も指定できるんだから、class よりは typename の方が適切だろうというのも分かります。
  • id:cx20
    > でも、こんなの (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 を使用しているコードがこれに該当します。
  • id:a-kuma3
    追加情報をありがとうございます(期待してたんですけど :-)

    手持ちの gcc 2.95.2 で、typename をつけて試してみたら、きちんと解釈されました。
    規格に新しく追加されたものを実装し始めの頃は、下位互換に気を使ってたけど、
    そのうち、コンパイラの性能を優先するようになった、というところかな。

  • id:cx20
    cppll ML の過去ログに、今回の話題のスレッドがありました。

    ■ スレッド: [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
  • id:a-kuma3
    >http://ml.tietew.jp/cppll/cppll/thread_articles/10073
    良いですね、これ。
    読み返しちゃいました。

    >>
    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 キーワードを覚えた」

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません