映射插入与对类型

时间:2015-09-26 07:39:33

标签: c++ stl

<int,int>类型的地图中插入元素时,我们必须再次明确提及类型作为对。 Isnt是多余的吗?

map<int,int> m1;
//m1.insert(1,1); //NOT OK since the pair type <int,int> not mentioned
m1.insert(pair<int,int>(1,1)); //OK

m1被声明为<int,int>。我们是否会尝试插入<int,int> e.g. m1.insert(pair<int,string>(1,"boo"))以外的任何元素?如果不是,那么在插入元素时再次写<int,int>是不是多余了?

编辑1:

这里详细解释一个小例子:

template<typename T1,typename T2>
class Test
{
public:
    template<typename T1>
    void fun1()
    {
        cout<<"This is called for T1 templatized fun1"<<endl;
    }
    template <typename T1,typename T2>
    void insert(pair<T1,T2> &obj)
    {
        cout<<obj.first<<" "<<obj.second<<endl;     
    }
};

int main()
{
    Test <int,int>obj; // Even though i have declared obj as type int,int, i am still able to call insert on type int,string
    obj.insert(pair<int,string>(1,"Anurag"));

这里我们清楚地看到我创建对象 obj 的类型与我调用 insert()的类型不同。 但我不明白成员函数map :: insert()如何确保类型与创建对象的类型相同? 我想到的一种方式是:

template <typename T3=T1,typename T4=T2> //where T1 and T2 are class typenames
void insert2(pair<T3,T4>& obj2)
{
    cout<<"Inside insert2 \n";
}

但即使这样也不允许,因为这是一个函数模板而不是类模板。我试着查看 map 的头文件,看看插入的声明但是更加困惑。

2 个答案:

答案 0 :(得分:4)

insert不是转发功能。只需使用括号初始化配对对象:

m1.insert({1, 1});

在C ++ 11中,emplace将转发参数。

m1.emplace(1, 1);

或者在C ++ 03中,make_pair

关于你的编辑:

这是一张非常不准确的地图表示。更准确的表示形式是这样的:

template <typename Key, typename T,
          class Compare = std::less<Key>,
          class Allocator = std::allocator<std::pair<const Key, T>>>
struct Test
{
    using value_type = std::pair<const Key, T>;
    using iterator   = typename std::allocator_traits<Allocator>::pointer;

    std::pair<iterator, bool> insert( const value_type& value )
    {
        // this calls emplace
    }
};

int main()
{
    Test<int, int> test;
    test.insert(std::pair<int, std::string>(1, "hello"));
}

哪个 会产生编译错误。当然,这就是为什么首先提供便利功能std::make_pair的原因。

答案 1 :(得分:1)

这是多余的,但事实并非如此。但是,您可以插入元素而无需重新指定<int,int>

这样,编译器足够聪明,可以找出make_pair函数的模板参数:

m1.insert(make_pair(1,1)); // equivalent o m1.insert(make_pair<int,int>(1,1));

或那样:

m1[1] = 1;

问题是:当您声明模板变量(pair是一个类型,因此pair<int,int>( 1, 1 )是模板变量声明)时,必须指定模板参数。但是,当你调用一个函数(make_pair实际上是一个函数)时,模板参数是可选的,编译器会尝试确定它们,只有在它失败时它才会抱怨。