当使用std :: pair或std :: map时,我们需要使用“first”或“second”来访问数据。但是这两个变量名称对于没有编写此代码的其他同事真正存储的内容并没有明确的含义。因此,如果我们可以为“第一”或“第二”创建别名,它将提高可读性。
例如,以下代码
static const std::map<std::string, std::pair<std::string, PFConvert>> COMM_MAP =
{ // keyword-> (caption, function)
{std::string("1"), {std::string("Big5 to Utf16LE"), &FileConvert_Big5ToUtf16LE}},
{std::string("2"), {std::string("Utf16LE to Utf8"), &FileConvert_Utf16LEToUtf8}},
{std::string("3"), {std::string("Utf8 to Big5"), &FileConvert_Utf8ToBig5}}
};
auto iterToExe = COMM_MAP.find(strTransType);
iterToExe->second.second();
iterToExe->second.second();
的可读性确实很差。
所以我尝试使用inherit来给出别名
template<typename PFComm>
class CCommContent : public std::pair<std::string, PFComm>
{
public:
std::string &strCaption = std::pair<std::string, PFComm>::first;
PFComm &pfComm = std::pair<std::string, PFComm>::second;
};
template<typename PFComm>
class CCommPair : public std::pair<std::string, CCommContent<PFComm>>
{
public:
std::string &strPattern = std::pair<std::string, CCommContent<PFComm>>::first;
CCommContent<PFComm> commContent = std::pair<std::string,CCommContent<PFComm>>::second;
};
template<typename PFComm>
class CCommMap : public std::map<std::string, CCommContent<PFComm>, std::less<std::string>, std::allocator<CCommPair<PFComm>>>
{};
但是这又出现了另一个问题:我必须宣布所有的ctors,虽然我可以打电话给基地ctors,但它似乎仍然不是一个聪明的方法。我只想制作别名。
一种简单的方法是使用宏......但是它绕过了类型检查。当使用嵌套结构时,调试时可能是一场噩梦。
任何建议或讨论都将不胜感激。
答案 0 :(得分:2)
某些typedef和accessor函数怎么样?
using CommEntry = std::pair<std::string, PFConvert>;
std::string const & getCaption(CommEntry const & e) { return e.first; }
PFConvert const & getFunction(CommEntry const & e) { return e.second; }
现在你可以说:
auto it = COMM_MAP.find(strTransType);
if (it != COMM_MAP.end())
{
auto & c = getCaption(it->second);
auto & l = getLabel(it->second);
// ...
}
如果您稍后更改了类型的详细信息,则只需调整访问者功能。
答案 1 :(得分:2)
为什么不简单地使用您自己的struct
和您自己的元素名称?
struct MyPair {
std::string strCaption;
PFComm pfComm;
};
使用C ++ 11,您可以轻松地创建它的新对象:
MyPair{std::string("Big5 to Utf16LE"), &FileConvert_Big5ToUtf16LE}}
如果您定义自己的operator<
,则可以std::set
作为地图:
bool operator<(const MyPair& a, const MyPair& b) {
return a.strCaption < b.strCaption;
}
typedef std::set<MyPair> MyPairMap;
当然,您可以嵌套自定义结构以形成更复杂的嵌套对,但在您的情况下,您可能需要考虑使用平面三元组:
struct CommMapEntry {
std::string number;
std::string caption;
PFComm pfComm;
};
bool operator<(const MyPair& a, const MyPair& b) {
return a.number<b.number;
}
static const std::set<CommMapEntry> COMM_MAP;
答案 2 :(得分:1)
好吧,在c ++ 11中,我们可以在派生类中使用using base::base
来使用基本ctors。但请注意,vs2013不符合此要求。 g ++ 4.8 do。