我有以下代码片段:

template < class MOEOT >
struct comp
{
    bool operator() (const MOEOT & a, const MOEOT & b)
    {
        return  ((a.objectiveVector()[1] < b.objectiveVector()[1]) || ((a.objectiveVector()[1] == b.objectiveVector()[1]) && (a.objectiveVector()[0] < b.objectiveVector()[0])));
    }
};

template < class MOEOT >
class moeo2DMinHypervolumeArchive : public std::set<MOEOT , comp < MOEOT > >
{
public:

    typedef typename std::set < MOEOT, comp<MOEOT>  >::iterator Iterator;

};

我在VS 2013中进行编译,并出现以下错误:
Error   1   error C2327: 'std::_Tree_comp<_Pr_has_storage,_Traits>::comp' : is not a type name, static, or enumerator

从我在其他地方阅读的内容来看,这似乎是VC中的错误。常见的解决方案是将typedef放在类之外。但是,在我的情况下这不起作用,因为typedef本身包含来自该类的模板参数。因此,将typedef放在外面是行不通的。

有谁能解决这个问题?

最佳答案

简短的答案:在声明嵌套的typedef时使用::comp<MOEOT>。或者,将comp类模板重命名为其他名称,例如my_special_comp

较长的答案:此行为是MSVC在模板定义内查找名称时的非标准行为的结果-通常称为两阶段查找。

基本上,错误消息中出现的_Tree_comp是Visual C++ 2013附带的标准库实现中std::set的间接基础。碰巧它具有一个称为comp的非静态数据成员。在嵌套的typedef中查找正在使用的不合格名称comp时,MSVC错误地在依赖库中查找并找到该声明。根据标准,这确实是一个错误,但是对于MSVC来说,这是众所周知的行为(他们正在考虑在将来对其进行修复,但请不要屏住呼吸)。

另一方面,::comp是一个限定ID,必须在全局命名空间中进行查找,从而避免名称冲突。

附带说明一下,Visual C++ 2015 RC附带的标准库中的std::set的实现已更改,不再导致此特定问题(查找仍然不可用,但名称comp不再存在导致此问题) 。

关于c++ - Visual Studio错误C2327,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30997630/

10-13 06:03