2015-11-02 10 views
12

Visual C++ 2015ではコンパイルされませんが、GCC 4.8.4ではコンパイルされないコードがあります。どちらが正しいのだろうか?問題のコードは、ここでは以下の通りです:テンプレートパラメータとしてオーバーライド指定子 - 有効ですか?

template <class T> class ATemplate; 
template <class R, class A1> 
    struct ATemplate<R(A1)>{ }; 

int main() 
{ 
    ATemplate<void(int)> x; 
// ATemplate<void(int)override> y; //---Does not compile!!! 
    return 0; 
} 

が、それは間違ってここに下記(またはconstの)指定子としてオーバーライドを使用することです。同じようなコードがGMockライブラリに存在し、実際の関数シグニチャーと同様に、テンプレートパラメータ(オーバーライドを含む)を生成するためにマクロ展開が使用されます。コメントアウト行取り外すとき

のVisual C++ 2015は、次のエラーを生成します。オーバーライドは無料機能(有効なポイント)の文脈では無意味であることを言及下記の回答

x.cpp(11): error C2062: type 'int' unexpected 
x.cpp(11): error C2976: 'ATemplate': too few template arguments 
x.cpp(4): note: see declaration of 'ATemplate' 
x.cpp(11): error C2079: 'y' uses undefined class 'ATemplate' 

ワン - これを行いますGCCの意味が間違っています。 const指定子もそのような場合(無償機能のために)無意味ですが、それにもかかわらず(VC++によって)???また、仮想指定子は宣言にのみ存在する必要があることを言及しています。これは(この定義が存在しないため)このケースには何の違いもありません。仮想キーワードについては、コードがコンパイルされているかどうかには何の違いもないので、派生クラスでは大丈夫ですが、オーバーライドの場合は大きな違いがあるのでOKではありません。 (GMockが行うように)がReturnType(ArgType引数)...可能CONSTを使用するか、マクロのパラメータとして指定をオーバーライドし、VCCによって課される制限が(余りにクランのために明らかにケース)をコンパイルしないように、このコードを引き起こす

。どちらが正しい?

標準では、このコンテキスト(テンプレートパラメータのコンテキスト)でオーバーライド指定子を使用しないと述べていませんか?

+0

私はおそらく何かを明らかに不足しているんだけど、どこ上書きする機能がありますか? –

+0

@KarolyHorvathそれは無関係です –

+0

@KarolyHorvath、はい、それは無関係です。投稿されたコードは最小限で、エラーが発生します。 –

答えて

8

g ++バグです。

標準は、二つの制作に仮想環境指定子秒を可能にする:関数定義(のみvirtualメンバ関数定義)およびメンバ宣言インチあなたの文脈はどちらでもありません。

GCCのバグの行動の短いデモ:投票によって判断

void foo(void) override;   // g++ rejects with message: 
            // virt-specifiers in 'foo' 
            // not allowed outside a class definition 
void (*bar)(void) override;  // g++ erroneously accepts 
typedef void baz(void) override; // g++ erroneously accepts 
5

標準によるとoverride指定子は、文脈に敏感であり、それはメンバ関数宣言の後を使用しています唯一の特別な意味を持っています。それ以外の場合は、予約済みのキーワードではありません。

2番目の例のコードは意味がないようです。

gcc-5.1.0(-Sフラグ付き)で両方の例をコンパイルしてみると、まったく同じアセンブリになります。

それは次のようなエラーが生じclang-3.7.0の下でコンパイルされません。

test.cpp:11:23: error: expected '(' for function-style cast or type construction 

Pracitcallyそれはあなたがそのようにオーバーライドを使うべきではないことを意味します。

+1

これは実際上ここの文脈ではどういう意味ですか? –

+0

@WernerErasmusそれはあなたがそれのように使用すべきでないことを意味します:) –

+0

が間違っています。あなたの例は私と同じではありません。 –

2

9.2クラスのメンバー(案N4140)

virt-specifier-seq: 
    virt-specifier 
    virt-specifier-seq virt-specifier 
virt-specifier: 
    override 
    final 

[9.2/8]

A virt-specifier-seq shall contain at most one of each virt-specifier. A virt-specifier-seq shall appear only in the declaration of a virtual member function (10.3).

だから私の知る限り、overrideが自由関数に適用することはできませんから、だから私はそれが自由な関数の署名/型に(たとえそれがconstのような型の一部であったとしても)許されるとは思わないでしょう。

+0

上記の文脈でのオーバーライドは関数定義には現れていませんが(私は定義を指定していません)、あなたの意見が分かります - しかし、派生したケースで仮想を省略することは問題ではありませんが、したがって、これは同じように扱うことはできません。 –

+0

@WernerErasmus私は何を意味するのか、明確にするために編集しました(私は願っています:)) – melak47

関連する問題