Следующий код компилируется без ошибок в 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/