详细说明类型是指Clang上的typedef错误

时间:2014-07-04 11:45:38

标签: c++ clang

使用此编译器Apple LLVM版本5.1(clang-503.0.40)我收到以下错误

代码在这里

test.h

  class media
  {
  public:
     typedef enum
     {
       audio,
       video,
       text,
       data
     }mediatype;
  };

TEST.CPP

 #include "test.h"

 int main()
 {
   enum media::mediatype medias[] = {media::audio, media::video};
   for (int i=0; (i < sizeof(medias) / sizeof(enum media::mediatype)); ++i)
   {


   }
 }

test.cpp:5:15:错误:详细类型是指typedef   enum media :: mediatype medias [] = {media :: audio,media :: video};

test.cpp:6:58:错误:对'mediatype'的引用不明确   for(int i = 0;(i&lt; sizeof(medias)/ sizeof(enum media :: mediatype)); ++ i)

如果我按如下方式删除enum关键字,则代码编译

  #include "test.h"

  int main()
  {
   media::mediatype medias[] = {media::audio, media::video};
   for (int i=0; (i < sizeof(medias) / sizeof(media::mediatype)); ++i)
   {


   }
 }

有人能说为什么clang抱怨

由于

3 个答案:

答案 0 :(得分:3)

在C ++中,您不需要将typedefenum一起使用:当您编写enum XYZ时,编译器会创建一个类型XYZ,以便您以后可以编写XYZ varOfTypeXYZ 1}},而不是enum XYZ varOfTypeXYZ

如下重写media将解决问题:

class media {
public:
     enum mediatype
     {
       audio,
       video,
       text,
       data
     };
};

Demo on ideone.

撰写enum media::mediatype的问题在于,您的声明不会创建enum代码mediatype,而是会创建一个名为mediatype的类型。您定义的enum是匿名的,因此无法正确解析引用enum media::mediatype

因此,解决此问题的另一种方法是向enum定义添加标记,如下所示:

class media {
public:
     typedef enum mediatype
     {
       audio,
       video,
       text,
       data
     } mediatype;
};

Demo on ideone.

答案 1 :(得分:1)

更改为:

class media {
public:
  enum mediatype {audio, video, text, data};
};


int main()
 {
   media::mediatype medias[] = {media::audio, media::video};
   for (int i=0; (i < sizeof(medias) / sizeof(enum media::mediatype)); ++i) {

   }
 }

你写的不是Clang的错,不是有效的C ++语法。

答案 2 :(得分:0)

typedef表示mediatype是类型名称,但不是枚举名称;所以enum media::mediatype不是引用它的有效方式。它只能称为media::mediatype

如果你把它改成更常见的习语:

enum mediatype {...};

然后它既是类型名称又是枚举名称,因此您可以将其称为enum media::mediatypemedia::mediatype

sizeof表达式中,您还可以引用一个对象而不是一个类型名称,因为如果数组类型发生变化,您仍然会得到正确的答案,因此它的错误性稍差:

sizeof(medias) / sizeof(medias[0])

更好的是,您可以使用辅助函数来提供数组的大小,这更容易出错,因为您不必复制数组名称,并且它不会给出如果您不小心将其应用于指针而不是数组,则结果不正确:

template <typename T, size_t N>
size_t array_size(T(&)[N]) {return N;}

for (size_t i = 0; i < array_size(medias); ++i) {}

或者,在C ++ 11中,您根本不需要计算大小:

for (media::mediatype media : medias) {}