在 C++ 中初始化静态 std::map<int, unique_ptr<int>>
Initializing a static std::map<int, unique_ptr<int>> in C++
这是一个与此 post 类似的问题。我认为最有前途的答案与模板化静态初始化有关。这是该答案的 class:
template <typename T, typename U>
class create_map
{
private:
std::map<T, U> m_map;
public:
create_map(const T& key, const U& val)
{
m_map[key] = val;
}
create_map<T, U>& operator()(const T& key, const U& val)
{
m_map[key] = val;
return *this;
}
operator std::map<T, U>()
{
return m_map;
}
};
用法:
std::map mymap = create_map<int, int >(1,2)(3,4)(5,6);
这对结构或 class 以及基本类型非常有用。我想做的是将它与 unique_prt<Structure\Class>
一起用作这样的值:
std::map mymap = create_map<DWORD, std::unique_ptr<Structure|Class>>(1, new Structure|Class())(2, new Structure|Class())
我正在尝试使用模板 class 以便我可以将值设置为任何类型。我从这个 post 得到了使用接口作为基础 class 然后派生的模板 class 来保存任何类型的值的想法。所以那些 classes 看起来像这样:
class MyFieldInterface
{
public:
int m_Size;
virtual ~MyFieldInterface() = default;
}
template <typename T>
class MyField : public MyFieldInterface {
T m_Value;
}
然后可以像我之前描述的那样设置地图:
std::map<DWORD, unique_ptr<MyFieldInterface>> mymap;
但是尝试用 create_map 初始化它失败了:
std::map mymap = create_map<DWORD, unique_ptr<MyFieldInterface>>(1, new MyField<DWORD>())(2, new MyField<char>())(3, new MyField<WORD>())
我得到的错误是这样的:
operator()
Error: no instance of constructor "create_map<T, U>::create_map [with T=DWORD, U=std::unique_ptr<MyFieldInterface, std::default_delete<MyFieldInterface>>]" matches the argument list
argument types are: (DWORD, MyField<DWORD>*)
所以我认为我需要一个构造函数和一个可以正确处理指针的 operator() 。我将两者都添加到 class:
create_map(const T& key, const U* val)
{
m_map[key] = val;
}
create_map<T, U>& operator()(const T& key, const U* val)
{
m_map[key] = val;
return *this;
}
我遇到了同样的错误。所以我尝试没有 *
:
create_map(const T& key, const U val)
{
m_map[key] = val;
}
create_map<T, U>& operator()(const T& key, const U val)
{
m_map[key] = val;
return *this;
}
我遇到了同样的错误。在我写这篇文章时,我意识到问题可能与继承有关,不一定与 create_map 的运算符有关。 你能帮我找出 operator() 定义或 base/derived class 定义吗?
请限制您的回答不包括 Boost C++ 库,因为我在这里工作时不允许使用它们。
编辑:根据T.C的要求更新了 MyFieldInterface。
这是一种可能的实现方式:
template <typename T, typename U>
class create_map
{
private:
std::map<T, U> m_map;
public:
create_map(T key, U val)
{
m_map.emplace(std::move(key), std::move(val));
}
create_map&& operator()(T key, U val) &&
{
m_map.emplace(std::move(key), std::move(val));
return std::move(*this);
}
operator std::map<T, U>() &&
{
return std::move(m_map);
}
};
注意按值获取参数,然后使用 emplace
将其移动到映射中,以及从 m_map
.
移动的转换运算符
我不知道 MSVC 2012 是否支持引用限定符。如果没有,则需要将其删除(即函数参数列表后的两个 &&
)。这样做的目的是强制 create_map
只能用作临时值。也可以强制转换运算符只被调用一次,但我在上面的代码中没有这样做。
现在您的调用不能使用裸 new
s,因为 1) 它不是异常安全的,并且 2) 原始指针不能隐式转换为 unique_ptr
s。不考虑数组的简单 make_unique
实现是
namespace util {
template<class T, class... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
}
然后您可以将 new MyField<DWORD>()
更改为 util::make_unique<MyField<DWORD>>()
*.
Demo.
* 使用合格的调用会禁用 ADL, if your call has arguments. A full implementation of make_unique
according to the spec can be found in the example code in N3656,make_unique
提案文件。
在 T.C 的指导下。由于 VC2012 中没有 make_unique,因此我从使用 unique_ptr<> 更改为 shared_ptr<>。
std::map mymap = create_map<DWORD, shared_ptr<MyFieldInterface>>(1, make_shared<MyField<DWORD>>())(2, make_shared<MyField<char>>())(3, make_shared<MyField<WORD>>())
这为我提供了我正在寻找的功能,而无需更改底层 类。虽然这符合我的需要,但我实际上会将 T.C. 的答案标记为正确,因为无论您使用哪个答案它都有效。
这是一个与此 post 类似的问题。我认为最有前途的答案与模板化静态初始化有关。这是该答案的 class:
template <typename T, typename U>
class create_map
{
private:
std::map<T, U> m_map;
public:
create_map(const T& key, const U& val)
{
m_map[key] = val;
}
create_map<T, U>& operator()(const T& key, const U& val)
{
m_map[key] = val;
return *this;
}
operator std::map<T, U>()
{
return m_map;
}
};
用法:
std::map mymap = create_map<int, int >(1,2)(3,4)(5,6);
这对结构或 class 以及基本类型非常有用。我想做的是将它与 unique_prt<Structure\Class>
一起用作这样的值:
std::map mymap = create_map<DWORD, std::unique_ptr<Structure|Class>>(1, new Structure|Class())(2, new Structure|Class())
我正在尝试使用模板 class 以便我可以将值设置为任何类型。我从这个 post 得到了使用接口作为基础 class 然后派生的模板 class 来保存任何类型的值的想法。所以那些 classes 看起来像这样:
class MyFieldInterface
{
public:
int m_Size;
virtual ~MyFieldInterface() = default;
}
template <typename T>
class MyField : public MyFieldInterface {
T m_Value;
}
然后可以像我之前描述的那样设置地图:
std::map<DWORD, unique_ptr<MyFieldInterface>> mymap;
但是尝试用 create_map 初始化它失败了:
std::map mymap = create_map<DWORD, unique_ptr<MyFieldInterface>>(1, new MyField<DWORD>())(2, new MyField<char>())(3, new MyField<WORD>())
我得到的错误是这样的:
operator()
Error: no instance of constructor "create_map<T, U>::create_map [with T=DWORD, U=std::unique_ptr<MyFieldInterface, std::default_delete<MyFieldInterface>>]" matches the argument list
argument types are: (DWORD, MyField<DWORD>*)
所以我认为我需要一个构造函数和一个可以正确处理指针的 operator() 。我将两者都添加到 class:
create_map(const T& key, const U* val)
{
m_map[key] = val;
}
create_map<T, U>& operator()(const T& key, const U* val)
{
m_map[key] = val;
return *this;
}
我遇到了同样的错误。所以我尝试没有 *
:
create_map(const T& key, const U val)
{
m_map[key] = val;
}
create_map<T, U>& operator()(const T& key, const U val)
{
m_map[key] = val;
return *this;
}
我遇到了同样的错误。在我写这篇文章时,我意识到问题可能与继承有关,不一定与 create_map 的运算符有关。 你能帮我找出 operator() 定义或 base/derived class 定义吗?
请限制您的回答不包括 Boost C++ 库,因为我在这里工作时不允许使用它们。
编辑:根据T.C的要求更新了 MyFieldInterface。
这是一种可能的实现方式:
template <typename T, typename U>
class create_map
{
private:
std::map<T, U> m_map;
public:
create_map(T key, U val)
{
m_map.emplace(std::move(key), std::move(val));
}
create_map&& operator()(T key, U val) &&
{
m_map.emplace(std::move(key), std::move(val));
return std::move(*this);
}
operator std::map<T, U>() &&
{
return std::move(m_map);
}
};
注意按值获取参数,然后使用 emplace
将其移动到映射中,以及从 m_map
.
我不知道 MSVC 2012 是否支持引用限定符。如果没有,则需要将其删除(即函数参数列表后的两个 &&
)。这样做的目的是强制 create_map
只能用作临时值。也可以强制转换运算符只被调用一次,但我在上面的代码中没有这样做。
现在您的调用不能使用裸 new
s,因为 1) 它不是异常安全的,并且 2) 原始指针不能隐式转换为 unique_ptr
s。不考虑数组的简单 make_unique
实现是
namespace util {
template<class T, class... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
}
然后您可以将 new MyField<DWORD>()
更改为 util::make_unique<MyField<DWORD>>()
*.
Demo.
* 使用合格的调用会禁用 ADL,make_unique
according to the spec can be found in the example code in N3656,make_unique
提案文件。
在 T.C 的指导下。由于 VC2012 中没有 make_unique,因此我从使用 unique_ptr<> 更改为 shared_ptr<>。
std::map mymap = create_map<DWORD, shared_ptr<MyFieldInterface>>(1, make_shared<MyField<DWORD>>())(2, make_shared<MyField<char>>())(3, make_shared<MyField<WORD>>())
这为我提供了我正在寻找的功能,而无需更改底层 类。虽然这符合我的需要,但我实际上会将 T.C. 的答案标记为正确,因为无论您使用哪个答案它都有效。