无法在 Visual Studio 2015 中将 typedef 转换为 std::pair

Posted

技术标签:

【中文标题】无法在 Visual Studio 2015 中将 typedef 转换为 std::pair【英文标题】:Can not convert typedef to std::pair in Visual Studio 2015 【发布时间】:2015-11-30 11:36:44 【问题描述】:

我尝试将一些项目从Visual Studio 2010 升级到2015。在2010 中一切正常,但在2015 中,我遇到了我不太理解的编译器错误。

我将代码压缩成一个 SSCCE

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <string>
#include <sstream>

#define UNUSED(x) (void(x))

class ColumnDef

public:
;

class XMLColumnDef

public:
    typedef std::pair<std::string, XMLColumnDef> pair;
    typedef std::pair<std::string, XMLColumnDef *> ptr_pair;

public:
    // Move constructor for moving the column into an container
    // without destroying it. Note that the source is no longer valid after 
    // such a move.
    XMLColumnDef(XMLColumnDef &oSource)
    
        mColumn = oSource.mColumn;
        oSource.mColumn = NULL;
    

    XMLColumnDef(ColumnDef *pColumn)
    
        mColumn = pColumn;
    

    virtual ~XMLColumnDef(void)
    
        delete mColumn;
    

private:
    ColumnDef *mColumn;
;

class XMLNodeObserver

public:
    typedef std::map<std::string, XMLNodeObserver *> map;
    typedef std::pair<std::string, XMLNodeObserver *> pair;
    typedef std::map<std::string, XMLColumnDef> row_def;

public:
    XMLNodeObserver(void) 
    virtual ~XMLNodeObserver(void) ;

    void addObserver(XMLNodeObserver::map &oNodeObserver, std::string const &oPath, XMLNodeObserver *oObserver = NULL)
    
        UNUSED(oNodeObserver);
        UNUSED(oPath);
        UNUSED(oObserver);
    
    void addColumnDef(XMLNodeObserver::map &oNodeObserver, std::string const &oPath, ColumnDef *oColumn, XMLNodeObserver *oObserver = NULL)
    
        if (oObserver == NULL)
            oObserver = this;

        addObserver(oNodeObserver, oPath, oObserver);

        XMLColumnDef::pair pr = std::make_pair(oPath, XMLColumnDef(oColumn));

        if (oObserver->mColumnDefs.find(oPath) != oObserver->mColumnDefs.end())
        
            // If a node already exists, we report an internal error, because this indicates a program bug and should be fixed.
            std::cerr << "INTERNAL ERROR: Duplicate rowdef key in XML node observer: " << oPath << std::endl;
        
        oObserver->mColumnDefs.insert(pr);
    

private:
    row_def mColumnDefs;
    bool mDebugMode;
;

int main()

    XMLNodeObserver o;
    XMLNodeObserver::map om;

    o.addColumnDef(om, "/testpath", new ColumnDef());

    std::cout << "\nDone! Press any key..." << std::endl;
    std::cin.ignore();

    return 0;

我在这一行得到的错误:

oObserver->mColumnDefs.insert(pr);

我得到的错误是这样的:

junk.cpp(104): error C2664: 'void std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::insert(std::initializer_list<std::pair<const _Kty,_Ty>>)': cannot convert argument 1 from 'XMLColumnDef::pair' to 'std::pair<const _Kty,_Ty> &&'
          with
          [
              _Kty=std::string,
              _Ty=XMLColumnDef,
              _Pr=std::less<std::string>,
              _Alloc=std::allocator<std::pair<const std::string,XMLColumnDef>>
          ]
          and
          [
              _Kty=std::string,
              _Ty=XMLColumnDef
          ]
junk.cpp(104): note: Reason: cannot convert from 'XMLColumnDef::pair' to 'std::pair<const _Kty,_Ty>'
          with
          [
              _Kty=std::string,
              _Ty=XMLColumnDef
          ]
junk.cpp(104): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

看起来Visual Studio 2015 不喜欢参数oPathconst &amp;,但这并不重要,因为它应该分配给pair 成员。

我还删除了 typedefs 并尝试使用长名称对其进行编译,但这似乎不是问题(无论如何也不应该),因为我遇到了同样的错误。

喜欢:

std::pair<std::string, XMLColumnDef> pr = std::pair<std::string, XMLColumnDef>(oPath, XMLColumnDef(oColumn));

【问题讨论】:

一个 SSCCE 需要 9 个不同的标头?!这不是说明问题的最小例子。例如,通过将映射值类型 XMLColumnDef&gt; 替换为 int,您将获得 大量 简化,但您仍然会遇到相同的错误(这是 const Key 问题) 【参考方案1】:

地图中的对的类型是 pair&lt;const key,value&gt; 而不是 pair&lt;key,value&gt;。尝试改用MyMapType::value_type typedef。免费获得!

示例:

typedef std::map<std::string, XMLNodeObserver *> MyMapType;
typedef MyMapType::value_type MyPairType;

【讨论】:

修复了编译错误,但现在我得到了一个新错误:error C2558: class 'XMLColumnDef': no copy constructor available or copy constructor is declared 'explicit'。但是我不能添加复制构造函数,因为指针应该被移动。 所以将ColumnDef* 成员替换为shared_ptr&lt;ColumnDef&gt;。这样就不用复制数据了,只需要共享指针即可。 当Node不再使用时,谁来发布呢?这就是为什么我使用移动成语。 shared_ptr 将在 XMLColumnDef 的最后一个副本被破坏时删除 ColumnDef* 对象。这正是您现在所需要的;) @Devolus:检查哪种方法会出现该错误。很有可能,您使用了错误的地图方法。你在使用emplace 吗?

以上是关于无法在 Visual Studio 2015 中将 typedef 转换为 std::pair的主要内容,如果未能解决你的问题,请参考以下文章

在 Visual Studio Code 中将语言更改为 JSX

如何在 Visual Studio 2015 调试中将“%”符号作为命令行参数 (argv) 传递?

如何在 Visual Studio 2013/2015 中将 Visual C++ 再分配文件 (.dll) 重新分配到我的应用程序

无法在 Visual Studio 中将 Visual C++ 运行时包引用添加到 Windows Phone 项目

无法在Visual Studio for Mac中将工具箱中的按钮添加到导航项

如何在 Visual Studio 2010 中将数据保存到本地数据库?