Карта emplace со значением, имеющим закрытый конструктор, приводит к C2664 (VC 12.0; C ++ 11) - PullRequest
2 голосов
/ 08 мая 2019

Следующий код компилируется без ошибок в Visual Studio 2015 (VC 14.0; C ++ 14):

#include <string>
#include <map>
#include <memory>

class Caller;
class SomeClass
{
private:
    friend class Caller;

    SomeClass(std::string& arg1, std::string& arg2)
    :
    m_arg1(arg1),
    m_arg2(arg2)
    { }

    std::string m_arg1;
    std::string m_arg2;
};

typedef std::shared_ptr<SomeClass> SomeClassPtr;

class Caller
{
public:
    void PopulateMap()
    {
        std::string key("test");
        m_map.emplace(key, new SomeClass { std::string("1"), std::string("2") });
    }

private:
    std::map<std::string, SomeClassPtr> m_map;
};

int main()
{
    Caller caller;
    caller.PopulateMap();
    return 0;
}

Однако при переходе на Visual Studio 2013 (VC 12.0; C ++ 11)C2664:

c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(600): error C2664: 'std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)' : cannot convert argument 2 from 'SomeClass *' to 'const SomeClassPtr &'
1>          with
1>          [
1>              _Kty=std::string
1>  ,            _Ty=SomeClassPtr
1>          ]
1>          Reason: cannot convert from 'SomeClass *' to 'const SomeClassPtr'
1>          Constructor for class 'std::shared_ptr<SomeClass>' is declared 'explicit'
...

В этом сообщении предполагается, что проблема в том, что аргумент-значение для std :: pair не может быть явно сконструирован.

Обходной путь - переслатьаргументы таковы:

m_map.emplace(std::piecewise_construct,
    std::forward_as_tuple(key),
    std::forward_as_tuple(new SomeClass(std::string("1"), std::string("2"))));

Теперь я понимаю, почему пример VC 12.0 терпит неудачу, но какая часть стандарта используется в исходном примере (VC 14.0) для его компиляции?

Википедия говорит, что Visual Studio 2015 имеет «улучшенную поддержку» C ++ 14/17: https://devblogs.microsoft.com/cppblog/c111417-features-in-vs-2015-rtm/

...