Delta_Fore
Delta_Fore

Reputation: 3271

Using std::make_pair requires explicit types with boost::flat_map for some reason

This simple test seems to have problems with the MSVC2015 compiler but I'm not sure why

    #include <boost\container\flat_map.hpp>

TEST_METHOD(TestMap) {
    // Map declaration
    boost::container::flat_map<std::string, float> map2;
    // This works
    map2.insert(std::make_pair<std::string, float>("foo", 1.0F));
    // This errors
    map2.insert(std::make_pair("foo", 1.0F));
    // This (my preferred solution) also errors with same error as previous line
    map2.insert({"foo", 1.0F});
    // This works fine but is less efficient so I don't want to do this
    map2["foo"] = 1.0F;
}

Error is

unittest1.cpp(54): error C2668: 'boost::container::flat_map<std::string,float,std::less<Key>,boost::container::new_allocator<std::pair<std::string,float>>>::insert': ambiguous call to overloaded function
1>          with
1>          [
1>              Key=std::string
1>          ]
1>  h:\users\mushfaque.cradle\documents\cpp\include\boost\container\flat_map.hpp(847): note: could be 'void boost::container::flat_map<std::string,float,std::less<Key>,boost::container::new_allocator<std::pair<std::string,float>>>::insert(std::initializer_list<std::pair<std::string,float>>)'
1>          with
1>          [
1>              Key=std::string
1>          ]
1>  h:\users\mushfaque.cradle\documents\cpp\include\boost\container\flat_map.hpp(752): note: or       'std::pair<boost::container::container_detail::vec_iterator<Pointer,false>,bool> boost::container::flat_map<std::string,float,std::less<Key>,boost::container::new_allocator<std::pair<std::string,float>>>::insert(boost::container::container_detail::pair<Key,T> &&)'
1>          with
1>          [
1>              Pointer=std::pair<std::string,float> *,
1>              Key=std::string,
1>              T=float
1>          ]
1>  h:\users\mushfaque.cradle\documents\cpp\include\boost\container\flat_map.hpp(737): note: or       'std::pair<boost::container::container_detail::vec_iterator<Pointer,false>,bool> boost::container::flat_map<std::string,float,std::less<Key>,boost::container::new_allocator<std::pair<std::string,float>>>::insert(std::pair<std::string,float> &&)'
1>          with
1>          [
1>              Pointer=std::pair<std::string,float> *,
1>              Key=std::string
1>          ]
1>  h:\users\mushfaque.cradle\documents\cpp\include\boost\container\flat_map.hpp(722): note: or       'std::pair<boost::container::container_detail::vec_iterator<Pointer,false>,bool> boost::container::flat_map<std::string,float,std::less<Key>,boost::container::new_allocator<std::pair<std::string,float>>>::insert(const std::pair<std::string,float> &)'
1>          with
1>          [
1>              Pointer=std::pair<std::string,float> *,
1>              Key=std::string
1>          ]

I don't understand why the type deduction doesn't work and I have to explicitly state it every time.

Upvotes: 1

Views: 731

Answers (1)

T.C.
T.C.

Reputation: 137330

The problem is that make_pair("Foo", 1.0f) returns a std::pair<const char*, float>, which is not a std::pair<std::string, float> but is convertible to one.

flat_map's insert, meanwhile, has a non-standard extra overload taking a movable_value_type&&, where movable_value_type is a boost::container::container_detail::pair<std::string, float>, which, apparently, can also be constructed from a std::pair<const char*, float>.

All user-defined conversions are equally good, the compiler doesn't know which one to pick, so it complains.

Upvotes: 3

Related Questions