C ++ - 尝试将类插入map时出错

时间:2016-10-10 17:06:54

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

我有一个类似于Missing artifact com.zeroalpha.struts:struts-el:jar:1.3.8的地图,我正在尝试将数据插入到地图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

我想我需要一双新眼睛才能看到这个我不知道这个问题是什么,谢谢!

修改

我正在尝试制作异构地图,并且每个数据类型都有一个类。但无论有多少,我仍然会得到同样的错误。

1 个答案:

答案 0 :(得分:0)

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

  • 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或更高版本,原始代码应该按原样编译,没有在这个答案中建议的任何修改。< / p>

[感谢AndyG指出它适用于更高版本的GCC&amp;铛。]

问题似乎是它没有从原始指针创建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在线测试。