3

ネストされた typedef の存在を判断しようとする次のコードを検討してください。

  #include<type_traits>
  struct foo;// incomplete type
  template<class T> 
  struct seq
  {
       using value_type = T;
  };
  struct no_type{};
  template<class T>
  struct check_type : std::true_type{};
  template<> 
  struct check_type<no_type> :std::false_type{};
  template<class T> 
  struct has_value_type
  {
    template<class U>
    static auto check(U const&)-> typename U:: value_type;
     static auto check(...)->no_type;  
    static bool const value = check_type<decltype(check(std::declval<T>()))>::value;
    using type = has_value_type;
  };
  int main()
  {
      char c[has_value_type<seq<foo>>::value?1:-1];
      (void)c;
  }

呼び出すhas_value_type<seq>::valueと、不完全な型の無効な使用としてコンパイル エラーが発生するようになりseq<foo>::value_typeました。decltype式に完全な型が必要ですか? そうでない場合、どうすればエラーを取り除くことができますか? コンパイルには gcc 4.7 を使用しています。

4

2 に答える 2

3

あなたのコードは有効な C++11 であり、呼び出しが prvalue であっても、decltype オペランドとして表示されるトップレベルの関数呼び出しが一時的なものを導入しないことを定義しています。

このルールは特に、自分のコードを有効にし、デストラクタのアクセス制限を決定するために必要な戻り値の型 (クラス テンプレートの特殊化の場合) のインスタンス化を防ぐために追加されました。

于 2012-05-14T09:06:57.943 に答える
2

decltype有効な式が必要であり、不完全な型を含む有効な式を持つことができます。ただし、あなたの場合の問題は

template<class U>
auto check(U const&) -> typename U::value_type;

の場合は戻り値の型fooUありseq<foo>ます。不完全な型を値で返すことはできないため、不適切な形式の式になってしまいます。void_<typename U::value_type>eg (with )の戻り値の型を使用するtemplate<typename T> struct void_ {};と、テストが機能しているように見えます。

于 2012-05-14T06:09:45.957 に答える