在模板方法中确定STL容器中项的数据类型



我正试图编写一个模板方法来处理STL容器中的项目。获取容器的详细信息很容易(并且我使用std::enable_if子句来允许仅在容器可以迭代时才调用此模板方法(检测begin()方法)),我还需要知道容器持有的数据类型。下面是有效的方法:

template <typename CONTAINER>
std::string doStuff(const CONTAINER & container) {
using CONTAINER_TYPE = typename CONTAINER::value_type;
}

如果我还能确定容器中保存的东西的类型,我可以在这个方法中使用if constexpr来做某些事情。下面的代码不能工作,但就像我想要的:

template <typename CONTAINER, typename ITEM>
std::string doStuff(const CONTAINER<ITEM> & container) {
using CONTAINER_TYPE = typename CONTAINER::value_type;
using ITEM_TYPE = typename ITEM::value_type;
}

不能以这种方式调用方法是完全有道理的,但是我能做些什么(调用方法或在方法内部使用元编程)来确定容器中项的类型呢?我想这样做,它在编译时是已知的。

(我已经尝试了decltype和invoke_result的几个排列和大量的搜索,但没有什么是相当工作。)我试过了,例如:

using ITEM_TYPE = std::invoke_result<&CONTAINER::begin>::type;

当然,这会返回一个需要解引用的迭代器类型,但是这里的"*"似乎没有像预期的那样工作。

您可以使用模板模板参数:

template <template <class, class...> class CONTAINER, class ITEM, class... REST>
std::string doStuff(const CONTAINER<ITEM, REST...>& container) {
using CONTAINER_TYPE = ITEM; // or `typename CONTAINER<ITEM, REST...>::value_type`
// This requires SFINAE to not match `ITEM`s without `value_type`:
using ITEM_TYPE = typename ITEM::value_type;
//...
}

您可以简单地添加额外的typename

template <typename CONTAINER>
std::string doStuff(const CONTAINER& container){
using CONTAINER_TYPE = typename CONTAINER::value_type;
using ITEM_TYPE = typename CONTAINER_TYPE::value_type;
}

可能有一些SFINAE(我将使用c++ 20方式)

template <typename CONTAINER>
std::string doStuff(const CONTAINER& container)
requires(
requires {
typename CONTAINER::value_type::value_type;
})
{
using CONTAINER_TYPE = typename CONTAINER::value_type;
using ITEM_TYPE = typename CONTAINER_TYPE::value_type;
}