问题描述和问题
我有一个模板
类Class1
。它包含在 map
中,我想在其中插入结构 A
或 B
。
问题在于结构A
和B
具有不同类型的成员变量。结构 A
有一个 std::string
成员变量,而结构 B
有一个 int
成员变量。
比较器基于结构A
。所以很明显,当我想插入一个结构 B 时,它不会编译。
Class1<B,B> c2;
c2.AddElement({1},{1});
我该如何解决该设计问题?例如,是否可以将 Class1
保留为 template
类并对 TestCompare
做一些事情?
我也有一个约束。我不能修改结构A
和B
。它们是用 C 代码编写的。我无权更改它们,因为它们是其他用户使用的外部代码。我只是尽可能地简化了代码。
源代码
代码编译于cpp.sh
#include <iostream>
#include <string>
#include <map>
typedef struct {
std::string a;
} A;
typedef struct {
int b;
} B;
template<typename T1, typename T2> class Class1 {
public :
struct TestCompare {
bool operator()(const T1 & lhs, const T1 & rhs) const {
return lhs.a < rhs.a;
}
};
Class1() {}
~Class1() {}
void AddElement(const T1 & key, const T2 & value) {
m.emplace(key, value);
}
private :
std::map<T1,T2,TestCompare> m;
};
int main()
{
Class1<A,A> c1;
c1.AddElement({"1"},{"1"});
// Problem here. Obviously it will not compile because the Operator is using
// the member variable of struct A.
//Class1<B,B> c2;
//c2.AddElement({1},{1});
//return 0;
}
新源代码
// Example program
#include <iostream>
#include <string>
#include <map>
typedef struct {
std::string a;
} A;
typedef struct {
int b;
} B;
bool operator<(const A & lhs, const A & rhs) {
return lhs.a < rhs.a;
}
bool operator<(const B & lhs, const B & rhs) {
return lhs.b < rhs.b;
}
template<typename T1, typename T2> class Class1 {
public :
Class1() {}
~Class1() {}
void AddElement(const T1 & key, const T2 value) {
m.emplace(key, value);
}
std::map<T1,T2> getMap() {
return m;
}
private :
std::map<T1,T2> m;
};
int main()
{
Class1<A,A> c1;
c1.AddElement({"1"},{"1"});
// Problem here. Obviously it will not compile because the Operator is using
// the member variable of struct A.
Class1<B,B> c2;
c2.AddElement({1},{1});
c2.AddElement({2},{2});
for(const auto &e: c2.getMap()) {
std::cout << e.first.b << " " << e.first.b << std::endl;
}
return 0;
}
最佳答案
我想您可以从 Class1
中删除 TestCompare
并为其创建模板。
template<typename T> struct TestCompare {
bool operator()(const T & lhs, const T & rhs) const {
// default implementation
return lhs < rhs;
}
};
template<typename T1, typename T2> class Class1 {
...
private :
std::map<T1,T2,TestCompare<T1>> m;
}
然后您可以针对 A
和 B
专门化 TestCompare
template<> struct TestCompare<A> {
bool operator()(const A & lhs, const A & rhs) const {
return lhs.a < rhs.a;
}
};
template<> struct TestCompare<B> {
bool operator()(const B & lhs, const B & rhs) const {
return lhs.b < rhs.b;
}
};
编辑:
实际上,您可以只使用 std::less
而不是 TestCompare
。这几乎是一回事,std::map
默认使用 std::less
。
关于c++ - 模板映射的设计问题采用不同的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51453798/