decltype需要包含完整类型的表达式吗?

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_typedecltype在表达式中需要完整的类型吗?如果不需要,我该如何消除错误?我正在使用gcc 4.7进行编译。


2
请问您能否发布错误信息? - Björn Pollex
来自gcc的错误:'seq <foo> :: value_type {也称为struct foo}'不完整类型的无效使用' seq <foo> :: value_type {也称为struct foo} '的前向声明' - abir
您是否在以后或根本不提供有关 foo 的定义?能否请更新您的代码,使其成为一个完整的示例(可以复制/粘贴/编译的示例)? - Björn Pollex
2个回答

3
您的代码是有效的C++11,它定义了一个作为decltype操作数出现的顶级函数调用即使是prvalue也不会引入临时变量。
这个规则特别添加是为了使类似您的代码有效,并防止实例化返回类型(如果它是类模板特化),否则需要确定析构函数的访问限制。

2

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

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

Useq<foo> 时,其返回类型为 foo。不能通过值来返回不完整的类型,因此将得到一个不良形式的表达式。你可以使用 void_<typename U::value_type> 作为返回类型(使用 template<typename T> struct void_ {}; 定义),这样你的测试似乎可以正常工作。


这个答案在C++11方面是不正确的。我会发表一份解释。 - Johannes Schaub - litb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接