【问题标题】:C++ - Errors when trying to insert class into mapC++ - 尝试将类插入地图时出错
【发布时间】:2016-10-10 17:06:53
【问题描述】:

我有一张像 map<string, unique_ptr<Base>> variables 这样的地图,我正在尝试将数据插入地图 variables.insert(make_pair("foo", new Int(10))),但我遇到了以下错误:

error: no matching function for call to ‘std::map<std::__cxx11::basic_string<char>, std::unique_ptr<Base>>::insert(std::pair<const char*, Int*>)’ variables.insert(make_pair("test", new Int(10)));

error: no type named ‘type’ in ‘struct std::enable_if<false, void>’ template<typename _Pair, typename = typename

这是我的代码:

class Base {
public:
    Base() {};
    virtual ~Base() {};
};

class Int : public Base {
public:
    Int(int i) {
        this->i = i;
    }
    Int operator=(int i) {
        this->i = i;
    }
    int i; 
};

void set() {
    map<string, unique_ptr<Base>> variables;
    variables.insert(make_pair("test", new Int(10)));
}

我想我需要一双新的眼睛来看看这个我不确定这是什么问题,谢谢!

编辑

我正在尝试制作异构映射,并且每种数据类型都有一个类。但是不管有多少,我仍然会遇到同样的错误。

【问题讨论】:

标签: c++ class c++11 dictionary


【解决方案1】:

注意:此答案仅适用于主要三个编译器的旧版本:

  • GCC:适用于 5.3.1 或更早版本。可能适用于 6.1.0 之前的任何版本,但我尚未对此进行测试。
  • Clang:适用于 3.7.1 或更早版本。可能适用于 3.8.0 之前的任何版本,但我尚未对此进行测试。
  • Visual Studio:适用于 19.00.23506.0 或更早版本。可能适用于 19.00.23720.0 之前的任何版本,但我尚未对此进行测试。

相反,如果您有 GCC 6.1.0 或更高版本、Clang 3.8.0 或更高版本,或者 Visual Studio 19.00.23720.0 或更高版本,则原始代码应按原样编译,无需进行此答案中建议的任何修改。

[感谢 AndyG 指出它适用于更高版本的 GCC 和 Clang。]


问题似乎是它没有从您的原始指针创建您的unique_ptr

如果你可以使用 C++14,试试std::make_unique()

void set() {
    map<string, unique_ptr<Base>> variables;
    variables.insert(make_pair("test", make_unique<Int>(10)));
}

如果你不能,那么试试这样的:

void set() {
    map<string, unique_ptr<Base>> variables;
    variables.insert(make_pair("test", unique_ptr<Int>(new Int(10))));
}

有趣的是,我注意到不同编译器处理此问题的方式略有不同。使用以下稍微修改过的代码版本作为测试程序:

#include <map>
#include <memory>
#include <iostream>

class Base {
public:
    Base() {};
    virtual ~Base() {};
};

class Int : public Base {
public:
    Int(int i) {
        this->i = i;
    }
    Int& operator=(int i) {
        this->i = i;

        // You forgot to return something.
        return *this;
    }
    int i; 
};

void set() {
    using namespace std;

    map<string, unique_ptr<Base>> variables;
    variables.insert(make_pair("test", new Int(10)));

    // C++14:
//    variables.insert(make_pair("test", make_unique<Int>(10)));

    // C++11:
//    variables.insert(make_pair("test", unique_ptr<Int>(new Int(10))));

    // Cheap hack for testing.
    cout << static_cast<Int*>(variables["test"].get())->i << endl;
}

int main() {
    set();
}

大多数编译器* 将无法编译它,除非初始行被注释掉并且其中一个修复未被注释。但是,online MSVC compiler 似乎能够很好地编译它,而无需取消注释任何一行。奇怪的是,MSVC available on Rextester 的版本在不取消注释两行之一的情况下无法编译它。

* 在线测试,使用 TutorialsPoint GCCMSVC 2015 online 和 Rextester ClangGCCMSVC

【讨论】:

  • 问题不在于原始指针。唯一指针有一个拥有所有权的构造函数。 Demo问题是OP没有给我们所有的细节。
  • @AndyG 很奇怪。除了您的链接和在线 MSVC 之外,它仍然对我不起作用。甚至尝试直接将代码从您的链接复制到Ideone,这是我以前没有尝试过的;它给出了与 TutorialsPoint & Rextester GCC 相同的错误。
  • 这就是为什么我建议明确制作指针,我认为这是大多数编译器出于某种原因共享的某种错误。
  • 到目前为止,我对智能指针只有基本的了解,这可能无济于事,所以我只是提出了一个简单的解决方案。
  • 我想知道 Ideone 到底在使用什么编译器。 Coliru 在 gcc 6.1.0 下编译没有问题 Demo 编辑:似乎是 gcc 5.1
猜你喜欢
  • 2013-10-26
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多