首页 > 解决方案 > 如何为检测其擦除功能的 unordered_map 定义一个概念

问题描述

我正在为无序关联容器编写一个 C++ 概念,即 std::unordered_map。我很难检测到擦除功能(也插入但暂时忽略它)。

这是我的概念尝试,遗憾的是,当我尝试调用需要它的模板化函数时它失败了。

template <class _ContainerType_>
concept InsertErasable = requires(_ContainerType_ a)
{
    { a.erase( _ContainerType_::const_iterator) } -> typename _ContainerType_::iterator;
};

我像这样使用它:

template<InsertErasable _ContainerType_>
inline void Test123( const _ContainerType_& container )
{
    return;
}

std::unordered_map<std::string, int> map;
::Test123(map);

错误 C7602:“Test123”:不满足关联的约束

使用最新的 Visual Studio 2019。

它应该检测此处显示的第一个擦除签名: https ://en.cppreference.com/w/cpp/container/unordered_map/erase

知道我做错了什么吗?

标签: c++c++-concepts

解决方案


老实说,我在实践中从未使用过概念,但我设法弄清楚这里出了什么问题。require 子句中的代码必须是一个表达式,而不是一个半表达式、半个函数定义。换句话说,它必须是一个可以编译的表达式,如果你把它放在一个常规函数中(https://en.cppreference.com/w/cpp/language/constraints部分的 require 子句)。要解决您的问题,您必须将概念子句内的代码调整为有效的 C++ 表达式。这可以通过以下两种方式之一来完成。任何一个:

template <class _ContainerType_>
concept InsertErasable = requires(_ContainerType_ a)
{
    {a.erase(a.cbegin())} -> typename _ContainerType_::iterator;
};

或者

template <class _ContainerType_>
concept InsertErasable = requires(_ContainerType_ a,_ContainerType_::const_iterator b)
{
    {a.erase(b)} -> typename _ContainerType_::iterator;
};

编译器资源管理器示例


推荐阅读