Search code examples
c++stlc++14forwarding-reference

Why Universal Reference concept not working for map insert in case of function pointers


Can someone explain why below piece of code is not working if I don't use explicitly std::pair with map insert :

#include <iostream>
#include <string>
#include <map>
#include <memory>
typedef std::shared_ptr<int>(*CreatorFunction)();
std::shared_ptr<int> test()
{
    std::shared_ptr<int> p(new int);
    return p;
}
int main()
{
  std::map<int, CreatorFunction> tmap; 
  tmap.insert(1,test); //this doesn't work
  tmap.insert(std::pair<int,CreatorFunction>(1,test)); //this works
 return 0;
}

My understanding is in c++14 we don't need to use std::pair as insert function definition is changed to accept universal reference as indicated below :

template <class P> pair<iterator,bool> insert (P&& val);

Solution

  • There is no any overload in std::map::insert that takes two arguments you should use std::make_pair. See the snippet below

    #include <iostream>
    #include <string>
    #include <map>
    #include <memory>
    
    #include <functional> // for std::function.
    
    // typedef std::shared_ptr<int>(*CreatorFunction)();
    typedef std::function<std::shared_ptr<int>()> CreatorFunction; // The c++ way.
    
    // Take a look at this function. std::shared_ptr<int> will automatically destroy the int* and might result in undefined.
    std::shared_ptr<int> test()
    {
        std::shared_ptr<int> p(new int);
        return p;
    }
    int main()
    {
        std::map<int, CreatorFunction> tmap; 
        tmap.insert(std::make_pair(1,test)); // edited this line
        tmap.insert(std::pair<int,CreatorFunction>(1,test)); // this works
        return 0;
    }