c++ - 如何正确推导从 std::set::begin() 返回的迭代器的取消引用类型?

标签 c++

我有一个模板类,其容器类型定义为 StorageType 模板。

StorageType mStorage;
....
void iterate( const std::function<bool( typename StorageType::value_type& )>& aFnc )
{
    for( auto it = mStorage.begin(); it != mStorage.end(); ++it )
    {
        aFnc( *it );
    }
}

这适用于大多数 STL 容器。但是当谈到 std::set 时,我面临一个问题,因为 mStorage.begin() 返回 const_iterator ,而 aFnc( *it ) 编译失败,因为 aFnc 函数需要 StorageType::value_type& 这是非常量的。

我尝试通过获取 std::set::begin 的结果并推导所接收的迭代器的取消引用类型来推导正确的类型,如下所示:

void iterate( std::function<void(typename std::iterator_traits<std::result_of<decltype(&std::set<ValueType>::begin)(std::set<ValueType>)>::type>::value_type& )>& aFnc )

但似乎 std::iterator_traits<>::value_type 返回非常量值类型,无论 std::set::begin() 中的实际迭代器取消引用 const T&。

我的目标是推断出作为参数提供的函数的正确签名。如果我将提到的函数定义为( const std::function& aFnc ),则所有内容都将为 std::set 进行编译,但不适用于其他容器类型(如 vector )。

最佳答案

std::set 不允许通过迭代器修改元素。 std::set::iteratorstd::set::const_iterator 都是常量迭代器(甚至可能是相同的类型)。这是因为 std::set 必须不允许重复。

因此,无论使用何种类型推导魔法,都不可能在这种 for 迭代中修改 set 的元素。如果 aFnc 需要修改元素,则不能使用 std::set

如果 aFnc 不修改其参数,那么您需要将参数设为常量:

using StoredType = typename StorageType::value_type;

void iterate(const std::function<bool(const StoredType&)>& aFnc)

关于c++ - 如何正确推导从 std::set::begin() 返回的迭代器的取消引用类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53594471/

相关文章:

c++ - 查找 std::wstring 的字符长度

c++ - 能不能用g++编译代码用Solaris Studio的Performance Analyser做性能分析?

c++ - 'for_each_n' 不是 C++17 中 'std' 的成员

c++ - Linux 管道 : Capturing realtime output of ping via popen

c++ - 我们可以继承自 Qt 容器吗?

c++ - 当我使用的库使用的库发生变化时,我的可执行文件是否需要重新链接?

c# - C# 中的 C++ union

c++ - Boost 程序选项 : force "="

c++ - 带有 cin 的 LCV 的循环不会在 C++ 中退出

c++ - 长字符串键的快速哈希函数