1

I am running into problems initialising maps with an initializer_list using Visual Studio 2013.

The following works fine:

#include <iostream>
#include <map>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
    map<string, string> m = { { "key_1", "value_1" }, { "key_2", "value_2" } };

    for (auto kv : m)
    {
        cout << "[" << kv.first << ", " << kv.second << "]" << endl;
    }

    return 0;
}

However, the following fails:

#include <iostream>
#include <map>
#include <string>

using namespace std;

class Foo {
public:
    // ctor
    Foo() {}
    // getter
    const map<string, string>& fooMap() const { return fooMap_; }
    // setter
    map<string, string>& fooMap() { return fooMap_; }
private:
    map<string, string> fooMap_;
};

int main(int argc, char* argv[])
{
    Foo foo;

    // Following two lines work
    // map<string, string> m = { { "key_1", "value_1" }, { "key_2", "value_2" } };
    // foo.fooMap() = m;

    // This assignment doesn't work
    foo.fooMap() = { { "key_1", "value_1" }, { "key_2", "value_2" } };

    for (auto kv : foo.fooMap())
    {
        cout << "[" << kv.first << ", " << kv.second << "]" << endl;
    }

    return 0;
}

with this error:

1>------ Build started: Project: map_test, Configuration: Release x64 ------
1>  map_test.cpp
1>map_test.cpp(22): error C2593: 'operator =' is ambiguous
1>          C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\map(212): could be 'std::map<std::string,std::string,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>> &std::map<_Kty,_Ty,std::less<_Ty>,std::allocator<std::pair<const _Kty,_Ty>>>::operator =(std::initializer_list<std::pair<const _Kty,_Ty>>)'
1>          with
1>          [
1>              _Kty=std::string
1>  ,            _Ty=std::string
1>          ]
1>          C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\map(166): or       'std::map<std::string,std::string,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>> &std::map<_Kty,_Ty,std::less<_Ty>,std::allocator<std::pair<const _Kty,_Ty>>>::operator =(std::map<_Kty,_Ty,std::less<_Ty>,std::allocator<std::pair<const _Kty,_Ty>>> &&)'
1>          with
1>          [
1>              _Kty=std::string
1>  ,            _Ty=std::string
1>          ]
1>          C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\map(150): or       'std::map<std::string,std::string,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>> &std::map<_Kty,_Ty,std::less<_Ty>,std::allocator<std::pair<const _Kty,_Ty>>>::operator =(const std::map<_Kty,_Ty,std::less<_Ty>,std::allocator<std::pair<const _Kty,_Ty>>> &)'
1>          with
1>          [
1>              _Kty=std::string
1>  ,            _Ty=std::string
1>          ]
1>          while trying to match the argument list '(std::map<std::string,std::string,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>, initializer-list)'
1>          with
1>          [
1>              _Kty=std::string
1>  ,            _Ty=std::string
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Is this an issue with the Visual Studio 2013 compiler (I am using Version 12.0.40629.00 Update 5)? It looks like a compiler issue to me but I wanted to double check in case I am missing something.


Edit: Actually, a much easier example of the same failure is given by:

#include <iostream>
#include <map>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
    map<string, string> m;
    // This does not work
    m = { { "key_1", "value_1" }, { "key_2", "value_2" } };

    for (auto kv : m)
    {
        cout << "[" << kv.first << ", " << kv.second << "]" << endl;
    }

    return 0;
}
Francis
  • 529
  • 4
  • 15
  • Your final "does not work" works fine with clang 3.9 and c++14 language levels. (and I assume later flavors). Are you *sure* you have the language compatibility turned up on your VC toolchain? – WhozCraig Nov 21 '17 at 23:37
  • Fully featured brace initialization is a c++11 feature, I'm not sure if that could be a VS2013 specific problem. – user0042 Nov 21 '17 at 23:43
  • 1
    @user0042 *Supposedly* (ymmv with MS) it is in VS2013, when properly language-level is configured in the compiler settings. [So claims MS](https://msdn.microsoft.com/en-us/library/hh567368.aspx). – WhozCraig Nov 21 '17 at 23:44
  • Thanks for the replies. I see from [here](https://stackoverflow.com/a/32020902/1771882) that there is an issue with using braced initialisation in an initialisation list but the error I am seeing appears to be with the assignment operator when the RHS is a braced initialisation. – Francis Nov 21 '17 at 23:51

0 Answers0