在c++中复制类似数据结构的任何基于模板的通用方法
any template-wise, generic way to copy similar data structure in c++?
我有一系列类似的结构,例如
map<key1, attr1>; map<key2, attr2>; ...,
同时,在对应关系中,一系列的阵列,
// JUST TO SHOW THE IDEA, NOT SYNTAX CORRECT
class {key_1; attr_1;} array [#]; class {key_2; attr_2;} array [#]; ...,
keyX和key_X共享相似的结构,以及attr,例如
struct key1 {int k1;}; class key_1 {int k_1;};
struct key2 {int k1; int k2;}; class key_2 {int k_1; int k_2;};
...
struct attr1 {int a1; int a2;}; class attr_1 {int a_1; int a_2;};
我需要编写一个函数,比如重载赋值运算符,将数据从map_series转换为另一个,反之亦然。
因此,与其进行逐个映射、逐键和int逐int,是否有一些基于模板的方法可以做到这一点,从而使代码具有通用性,或者保存更多的代码行?做这件事的明智方法是什么?
编辑1:
不幸的是,由于我们的遗留系统,结构(例如key1、key_1)之间的类型转换不能作为C++基元工作,因此还必须提供转换函数。
编辑2:
受到J.N.答案的启发,有可能有这样的东西吗:
template <class KeyMap, class ValueMap, class KeyArr, class ValueArr> void convert (map<KeyMap, ValueMap>, class {KeyArr, ValueArr} array[]){};
如何生成键和属性的转换?像
template <class KeyMap, class KeyArr> void convert_key(KeyMap, KeyArr){}
好的,让我们假设我们有这个:
map<KeyTypeM, ValueTypeM> m1;
struct Type1 {
KeyTypeS Key;
ValueTypeS Value;
};
让我们先定义转换函数:
Type1 ConvType1(const KeyTypeM& key, const ValueTypeM& value)
{
Type1 result;
result.Key = f(key); // user dependent
result.Value = f(value); // user dependent
return result;
}
然后,在C++中,不能返回数组。实际上,你通常不使用数组,人们通常更喜欢std::vector
。(如果你真的需要一个数组,那么你需要分配它并返回一个指向它的指针,或者将它封装在智能指针中)然后浏览地图中的值并将其推送到向量中就足够了:
vector<Type1> ConvertType1(map<KeyTypeM, ValueTypeM>& input)
{
vector<Type1> result;
for (auto& pair : input) // assumes C++11
result.push_back( ConvType1(pair.first, pair.second) );
return result;
}
注意:如果您没有C++11编译器,请使用:
for (map<KeyTypeM, ValueTypeM>::iterator it = m.begin(); it != m.end(); ++it)
result.push_back( ConvType1(it->first, it->second) );
这将完成一张地图和一种类型的工作。现在我们可以使用模板来概括转换函数:
template <class OutType, class KeyType, class ValueType, class Converter>
vector<OutType> Convert(map<KeyType, ValueType>& input, Converter conv)
{
vector<OutType> result;
for (auto& pair : input)
result.push_back( conv(pair.first, pair.second) );
return result;
}
并像这样使用:
auto v1 = Convert<Type1>(m1, &ConvertType1);
auto v2 = Convert<Type2>(m2, &ConvertType2);
...
您可以更进一步,创建一个使用boost::mpl
转换的类型列表,但这应该是另一个问题。
编辑:概括类型的转换
正如您所提到的,没有通用的方法来转换类型,我们必须编写所有的转换函数。因此,我们唯一能做的就是通过实现这样的隐式转换运算符使其更加优雅:
struct KeyTypeM
{
... // normal members
operator KeyTypeS() const
{
// do the conversion here
}
};
// suppose we have the same for ValueTypeM and ValueTypeS
// We can now use a single convert function:
template <class OutType, class KeyTypeM, class ValueType M>
OutType ConvertToStruct(const KeyTypeM& key, const ValueTypeM& value)
{
OutType result;
result.Key = key; // will call the implicit conversion
result.Value = value;
return result;
}
这简化了我们的转换功能(更新以考虑阵列)
template <class OutType, class KeyType, class ValueType>
void Convert(map<KeyType, ValueType>& input, OutType out[])
{
// out must have been initialized to a proper size to hold all the elements.
unsigned cursor = 0;
for (map<KeyTypeM, ValueTypeM>::iterator it = m.begin(); it != m.end(); ++it, ++cursor)
out[cursor] = ConvertToStruct<OutType>(it->first, it->second);
}
EDIT2:我们可以使用std::pair
来推广数组结构:
template <class OutType, class KeyTypeM, class ValueType M>
OutType ConvertToStruct(const KeyTypeM& key, const ValueTypeM& value)
{
OutType result;
result.first = key; // will call the implicit conversion
result.second = value;
return result;
}
template <class OutKey, class OutValue, class KeyType, class ValueType>
void Convert(map<KeyType, ValueType>& input, std::pair<OutKey, OutValue> out[])
{
// out must have been initialized to a proper size to hold all the elements.
unsigned cursor = 0;
for (map<KeyTypeM, ValueTypeM>::iterator it = m.begin(); it != m.end(); ++it, ++cursor)
out[cursor] = ConvertToStruct<OutType>(it->first, it->second);
}
// Use this way:
std::pair<OutKey, OutValue> arr[m.size()];
Convert(m, arr);
相关文章:
- 公开最直接的基类模板名称
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 引用基类模板的成员变量的简单方法
- 为什么 std::erase(std::erase_if) 不是适用于<algorithm>任何容器的模板?
- 类成员函数参数列表是否可以依赖于模板参数?
- 检查该类在编译时C++中是否有任何基类
- 使用基类模板检测is_base_of
- std::任何只用于移动的模板,其中副本ctor内的static_assert等于编译错误,但为什么
- 依赖于模板的错误
- 将 c++ 类成员函数专用于模板类
- C++ 使函数调用依赖于模板参数
- c ++如何将模板应用于模板类的孩子/朋友?
- 是否可以从构造函数自动推断基类模板参数?
- 如何修复"没有依赖于模板参数的参数'glGenVertexArrays'......"C++ 中的错误
- 如何转发声明依赖于变量定义的类,而变体定义又依赖于模板化类?
- C++包含任何类型的模板类对象的映射
- 通过派生类模板参数指定基类模板参数之一。如何使用基类的 using 声明
- 你能在任何独立于架构的低级语言中获得更小的整数吗?
- C 错误:从(基类模板)到子类的无效转换
- 如何确保 "<<" 运算符适用于模板化 ADT 定义中的任何泛型类型?