decltype需要一个涉及完整类型的表达式吗?

时间:2012-05-14 05:45:09

标签: c++ c++11

考虑以下代码,尝试确定是否存在嵌套的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_typedecltype需要表达式中的完整类型吗?如果没有,我该如何删除错误?我正在使用gcc 4.7进行编译。

2 个答案:

答案 0 :(得分:3)

您的代码是有效的C ++ 11,它定义了一个出现为decltype操作数的顶级函数调用,即使调用是prvalue也不会引入临时函数。

此规则专门用于使您的代码有效并防止实例化返回类型(如果它是类模板特化),否则需要确定析构函数的访问限制。

答案 1 :(得分:2)

decltype需要一个有效的表达式,你当然可以拥有一个涉及不完整类型的有效表达式。然而,你的问题是

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

fooU时返回类型seq<foo>。您不能按值返回不完整的类型,因此您最终会得到格式错误的表达式。您可以使用返回类型,例如void_<typename U::value_type>(使用template<typename T> struct void_ {};),您的测试似乎有效。