visual studio中的神秘警告(4180)

cryptic warning in visual studio (4180)

本文关键字:警告 4180 studio visual      更新时间:2023-10-16
1>c:program filesmicrosoft visual studio 10.0vcincludemap(229): warning C4180: 
     qualifier applied to function type has no meaning; ignored
1>          d:...gmproject.h(122) 
            : see reference to class template instantiation 'std::map<_Kty,_Ty>' 
            being compiled
1>          with
1>          [
1>              _Kty=GMProject::DuplicateTy,
1>              _Ty=GMProject::DuplicateFn
1>          ]

我的类有这些类型定义(pTree是一个容器):

typedef void *DuplicateFn(pTree&, const pTree&); 
enum DuplicateTy {
    SKIP,
    OVERWRITE,
    ASK
};
typedef std::map<DuplicateTy, DuplicateFn> DuplicateMapTy;

和第122,123行分别是:

static const DuplicateMapTy DuplicateFns;
static DuplicateMapTy DuplicateFns_INIT();

我如何指示这个映射不能更改-并使它对类是静态的?我的目标是创建一个映射,这样我就可以从枚举中"获取"一个函数指针。(客户端代码将提供枚举,然后类本身将枚举解析为函数)。

这个问题与const映射无关:这是一个警告,因为std::map::at()的const版本的返回类型是const mapped_type&。下面的代码同样会产生警告:

typedef void *DuplicateFn();
typedef std::map< int, DuplicateFn > DuplicateMapTy;
DuplicateMapTy DuplicateFns;

这里map的at的返回类型是

const DuplicateFn&

虽然这个警告有它的地方(尽管我不太确定在这种特殊情况下它是否符合标准),在这种情况下,在使用map的代码中局部禁用它应该没有什么害处,或者如果你不喜欢编译麻烦,可以将函数指针包装成一个简单的结构体。

edit正如Gorpik在下面的评论中指出的那样,这实际上是在该特定位置生成的,尽管没有使用该函数。看起来VS编译器在寻找警告时确实有点咄咄逼人:它确实考虑声明。

template< class T >
struct CheckMe
{
  const T& at() //warning C4180 pops up
  {
    //gets not instantiated hence no error for missing returntype
  }
};
CheckMe< DuplicateFn > check;