取消引用模板化typedef的成员

时间:2018-11-27 19:47:08

标签: c++ templates typedef dereference

我使用的图书馆有:

typedef std::map<std::wstring, std::vector<std::wstring>* > XmlRecord_t;

在此地图上进行迭代时,我会创建变量,例如:

std::wstring& key( mapIter->first );
std::vector<std::wstring>* values( mapIter->second );

这很好。然后,我想迭代这些值,所以我有一个for循环,例如:

for( std::vector<std::wstring>::const_iterator it = vals->cbegin();... )

这很好,效果很好。

现在,仅出于好奇,我想重用库的typedef名称,以防typedef定义更改或保持整洁。换句话说,我想使用:

typedef XmlRecord_t::mapped_type VecPtr;
VecPtr values( mapIter->second )

代替:

std::vector<std::wstring>* values( mapIter->second );  

到目前为止有效。唯一的问题来自for循环。我的typedef是指向vector的指针,而不仅仅是vector。所以我不能用那个typedef来代替:

std::vector<std::wstring>::const_iterator

以我所知道的任何方式。

因此,我的问题可以概括为:如果您有一个库(代码,我不允许您修改):

typedef map<KEY, T*> Map2Ptrs

如何在代码中使用Map2Ptrs来获得T(没有指针)?要制作typedef类型的T吗?

显然,图书馆作者应该已经创建:

typedef std::vector<std::wstring>  XmlRecordVals;
typedef std::map<std::wstring, XmlRecordVals* > XmlRecord_t;

相反。但是我只有上面的原始XmlRecord_t可用于;(

2 个答案:

答案 0 :(得分:2)

假设Map2Ptrs始终是std::map,则可以分别使用Map2Ptrs::key_typeMap2Ptrs::mapped_type检查其键和映射类型。

可以使用std::remove_pointer_t(需要C ++ 14和#include<type_traits>)从类型中删除指针,例如:

using T = std::remove_pointer_t<Map2Ptrs::mapped_type>;

在现代C ++中,您可能不应该手动指定迭代器类型,可以轻松推导它们:

for( auto it = vals->cbegin();... )

此外,还有range-for,它消除了手动指定迭代器的需要,并且语法更好:

for(const auto& x : *vals) { /* Do something with x */ }

从C ++ 17开始,可以使用地图结构化绑定:

for(const auto& [key, vals] : theMap) {
    /* Do something with key and vals */
}

答案 1 :(得分:1)

def self.limit_by_total_price(budget) subquery = select('leads.*, sum(leads.sms_price) over(order by leads.id) as total_price') from(subquery, :leads).where('total_price < ?', budget) end cppreference中的示例:

std::remove_pointer

因此,如果您将指向矢量类型的指针作为别名,则可以通过以下方式获取迭代器:

print_is_same<int, std::remove_pointer<int*>::type>();  // true

尽管我强烈建议您更改实际别名以代替删除指针。