2017-01-18 22 views
2

IのVisual Studioとg ++ではなく、クランに下罰金コンパイルする次のコード、私はエラーを取得する必要があり:クランテンプレート不完全な型

ああ

「エラー 『NS :: B』は不完全な型です」
#pragma once 
namespace ns 
{ 
    class B; 

    class A 
    { 
     friend class B; 
     class Inner 
     { 
     public: 
      int x; 
      Inner(int x) : x(x) {} 
     }; 
    public: 
     template<typename T> 
     T getB(int i) 
     { 
      B b = B(Inner(i)); 
      return T(b); 
     } 

    }; 
} 

Bhの

#pragma once 
#include "A.h" 

namespace ns 
{ 
    class B 
    { 
     A::Inner i; 
    public: 
     B(A::Inner i) : i(i) 
     {} 

     operator int() const 
     { 
      return i.x; 
     } 
    }; 
} 

main.cppに

#include "A.h" 
#include "B.h" 

int main() 
{ 
    ns::A a; 
    return a.getB<int>(5); 
} 

テンプレートがインスタンス化されるまでにBが完了するので、コードがうまくいくはずです。これは正しいです?もしそうなら、Clangの問題を回避する方法はありますか?

+0

無関係なサイドノート: 'の#include "a.h"' main.cppにして無意味です。 – SingerOfTheFall

+3

@SingerOfTheFallヘッダーを繰り返し含めるのはうまくいいですが、ここには表示されていないガードが含まれている必要があります。 – Potatoswatter

+0

@Potatoswatter申し訳ありませんが、私はコピーするときにそれらを見逃しました。 –

答えて

4

プログラムが不正です。診断は必要ありません。

[temp.res]/8

The program is ill-formed, no diagnostic required, if:

  • [...]
  • a hypothetical instantiation of a template immediately following its definition would be ill-formed due to a construct that does not depend on a template parameter, or
  • [...]
+1

...一つの解決策は、 'A :: getB'を' A.h'で前方宣言し、 'B.h'で定義することです。 – Potatoswatter

+0

@Potatoswatter素晴らしい、ありがとう。 VSとg ++でなぜそれがうまくいくのか考えていますか? –

+2

@MikeJones:ビジュアルではテンプレートに対する2回のパスチェック(標準に準拠していない)は行われないため、依存しないコードはチェックされません。 g ++では(2回のパスチェックを行います)、それらを診断する機会がありません。 – Jarod42

関連する問題