にゃははー

はへらー

先日の基底クラスの型名云々のやつ

id:hito_hppさんから基底クラス名は派生クラスのスコープにあるというありがたいお話を頂いたが、それでもたまに引っかかったので、それについていくつかのコンパイラで試してみた。普通なら仕様書嫁だろうが、C++03(もしくは98)の仕様書を私は持っていない。なので実際問題現行仕様に含まれているかを確認することができない。ので、誰かくだs(殴
いや、もちろん金かかるのは分かってますよ。支払いがめんどそうってのがあるので敬遠。そのうち手に入れよう。


で、テストコードは以下の通り。

namespace hoge
{

template < typename >
struct fuga {};

template < typename >
struct S1 : public fuga< int >
{ typedef fuga base; };
S1< int > s1;

template < typename T >
struct S2 : public fuga< T >
{ typedef fuga base; };
S2< int > s2;

} // namespace hoge

template < typename >
struct S3 : public hoge::fuga< int >
{ typedef fuga base; };
S3< int > s3;

template < typename >
struct S4 : public hoge::fuga< int >
{ typedef hoge::fuga base; };
S4< int > s4;

template < typename T >
struct S5 : public hoge::fuga< T >
{ typedef fuga base; };
S5< int > s5;

template < typename T >
struct S6 : public hoge::fuga< T >
{ typedef hoge::fuga base; };
S6< int > s6;

namespace piyo
{

template < typename >
struct S7 : public hoge::fuga< int >
{ typedef fuga base; };
S7< int > s7;

template < typename >
struct S8 : public hoge::fuga< int >
{ typedef hoge::fuga base; };
S8< int > s8;

template < typename T >
struct S9 : public hoge::fuga< T >
{ typedef fuga base; };
S9< int > s9;

template < typename T >
struct S10 : public hoge::fuga< T >
{ typedef hoge::fuga base; };
S10< int > s10;

} // namespace piyo

思いついた10通りやってみました。msvcがtemplateを実体化させない限りエラーを吐かなかったのでそれぞれインスタンスを作ってます。

で、スコープに入るということを考えると、S4,6,8,10はnamespaceを指定とかしてるので多分通らない。ってだけになると多分おk?(だれか仕様plz)

対象としたコンパイラは手元にあるやつをできるだけ使いました。
gcc-4.3 (Ubuntu 4.3.5-3ubuntu1) 4.3.5
gcc-4.4 (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
gcc-4.5 (Ubuntu/Linaro 4.5.1-7ubuntu2) 4.5.1
gcc-4.6 (GCC) 4.6.0 20101031 (experimental)
clang version 2.9 (trunk 117849)
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86

ではでは結果ー ものすごく長いので適当に飛ばすなり・・・

gcc-4.3 (Ubuntu 4.3.5-3ubuntu1) 4.3.5

$ g++-4.3 hoge.cpp
hoge.cpp:9: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:14: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:21: error: ‘fuga’ does not name a type
hoge.cpp:26: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:31: error: ‘fuga’ does not name a type
hoge.cpp:31: note: (perhaps ‘typename hoge::fuga::fuga’ was intended)
hoge.cpp:36: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:44: error: ‘fuga’ does not name a type
hoge.cpp:49: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:54: error: ‘fuga’ does not name a type
hoge.cpp:54: note: (perhaps ‘typename hoge::fuga::fuga’ was intended)
hoge.cpp:59: error: invalid use of template-name ‘hoge::fuga’ without an argument list

なんと・・・全てでエラー。

gcc-4.4 (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5

$ g++-4.4 hoge.cpp
hoge.cpp:9: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:14: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:21: error: ‘fuga’ does not name a type
hoge.cpp:26: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:31: error: ‘fuga’ does not name a type
hoge.cpp:31: note: (perhaps ‘typename hoge::fuga::fuga’ was intended)
hoge.cpp:36: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:44: error: ‘fuga’ does not name a type
hoge.cpp:49: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:54: error: ‘fuga’ does not name a type
hoge.cpp:54: note: (perhaps ‘typename hoge::fuga::fuga’ was intended)
hoge.cpp:59: error: invalid use of template-name ‘hoge::fuga’ without an argument list

GCC4.3に引き続き全てでエラー。

gcc-4.5 (Ubuntu/Linaro 4.5.1-7ubuntu2) 4.5.1

$ g++-4.5 hoge.cpp
hoge.cpp:14:11: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:26:11: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:31:11: error: ‘fuga’ does not name a type
hoge.cpp:31:11: note: (perhaps ‘typename hoge::fuga::fuga’ was intended)
hoge.cpp:36:11: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:49:11: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:54:11: error: ‘fuga’ does not name a type
hoge.cpp:54:11: note: (perhaps ‘typename hoge::fuga::fuga’ was intended)
hoge.cpp:59:11: error: invalid use of template-name ‘hoge::fuga’ without an argument list

S1,3,7が通っていますね。継承するクラスが自明なcomplete typeなら引けるようです。それでもnamespaceは余計らしい。

gcc-4.6 (GCC) 4.6.0 20101031 (experimental)

$ g++-4.6 hoge.cpp
hoge.cpp:14:11: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:26:11: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:31:11: error: ‘fuga’ does not name a type
hoge.cpp:31:11: note: (perhaps ‘typename hoge::fuga::fuga’ was intended)
hoge.cpp:36:11: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:49:11: error: invalid use of template-name ‘hoge::fuga’ without an argument list
hoge.cpp:54:11: error: ‘fuga’ does not name a type
hoge.cpp:54:11: note: (perhaps ‘typename hoge::fuga::fuga’ was intended)
hoge.cpp:59:11: error: invalid use of template-name ‘hoge::fuga’ without an argument list

GCC4.5と同じですね。

clang version 2.9 (trunk 117849)

$ clang++ hoge.cpp
hoge.cpp:14:11: error: use of class template fuga requires template arguments
{ typedef fuga base; };
          ^
hoge.cpp:5:8: note: template is declared here
struct fuga {};
       ^
hoge.cpp:26:17: error: use of class template hoge::fuga requires template
      arguments
{ typedef hoge::fuga base; };
                ^
hoge.cpp:5:8: note: template is declared here
struct fuga {};
       ^
hoge.cpp:31:11: error: unknown type name 'fuga'
{ typedef fuga base; };
          ^
hoge.cpp:36:17: error: use of class template hoge::fuga requires template
      arguments
{ typedef hoge::fuga base; };
                ^
hoge.cpp:5:8: note: template is declared here
struct fuga {};
       ^
hoge.cpp:49:17: error: use of class template hoge::fuga requires template
      arguments
{ typedef hoge::fuga base; };
                ^
hoge.cpp:5:8: note: template is declared here
struct fuga {};
       ^
hoge.cpp:54:11: error: unknown type name 'fuga'
{ typedef fuga base; };
          ^
hoge.cpp:59:17: error: use of class template hoge::fuga requires template
      arguments
{ typedef hoge::fuga base; };
                ^
hoge.cpp:5:8: note: template is declared here
struct fuga {};
       ^
7 errors generated.

Oh... 流石clang。目にやさしいですね。色つきで出せないのが悔やまれます。
が、エラーはエラー。GCC4.5/4.6と同じようです。

最近のコンパイラの挙動から、テンプレート実引数に依存しなければ引けるのではないかと予想を立てたけどどうなんだろ。仕様書だれk(
最近のドラフトを読むとして、どこを読めばいいんだろう。継承関係からかな?

んーなんともいえん。
まぁここらへんのエラーがあるからBoostはわざわざめんどいことしてるんですねぇ。


そして大本命(笑) まぁお遊び程度のつもりで。
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86

>cl hoge.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

hoge.cpp
hoge.cpp(26) : error C2955: 'hoge::fuga' : クラス テンプレート を使用するには テンプレート 引数リストが必要です
        hoge.cpp(5) : 'hoge::fuga' の宣言を確認してください。
        hoge.cpp(27) : コンパイルされたクラスの テンプレート のインスタンス化 'S4<>' の参照を確認してください
        with
        [
            =int
        ]

S4でつまずいてますね。が、他のエラーが出ないのが何か怪しい。ということでS4をコメントアウトして再実験。

>cl hoge.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

hoge.cpp
hoge.cpp(36) : error C2955: 'hoge::fuga' : クラス テンプレート を使用するには テンプレート 引数リストが必要です
        hoge.cpp(5) : 'hoge::fuga' の宣言を確認してください。
        hoge.cpp(37) : コンパイルされたクラスの テンプレート のインスタンス化 'S6' の参照を確認してください
        with
        [
            T=int
        ]

今度はS6か。一気に出してくれないかなぁ... S6を(ry

>cl hoge.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

hoge.cpp                                                                    
hoge.cpp(49) : error C2955: 'hoge::fuga' : クラス テンプレート を使用するに>    は テンプレート 引数リストが必要です
        hoge.cpp(5) : 'hoge::fuga' の宣言を確認してください。
        hoge.cpp(50) : コンパイルされたクラスの テンプレート のインスタンス>    化 'piyo::S8<>' の参照を確認してください
        with
        [
            =int
        ]

も、もしや・・・

>cl hoge.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.
                       
hoge.cpp                                                                    
hoge.cpp(59) : error C2955: 'hoge::fuga' : クラス テンプレート を使用するに>    は テンプレート 引数リストが必要です
        hoge.cpp(5) : 'hoge::fuga' の宣言を確認してください。
        hoge.cpp(60) : コンパイルされたクラスの テンプレート のインスタンス>    化 'piyo::S10' の参照を確認してください 
        with
        [
            T=int
        ]
>cl hoge.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

hoge.cpp                                                                        
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:hoge.exe
hoge.obj
LINK : fatal error LNK1561: エントリー ポイントを定義しなければなりません。

(@@;) どういうことだ...
"あの"msvcが・・・

さて、みなかったことにしよう。