c++ - enable_if 检查迭代器的值类型是否是一对

标签 c++ c++11

我想为值类型为一对的迭代器编写一个专门的模板函数。我的期望是这应该匹配 std::map 的迭代器。

为了检测对:

template <typename>
struct is_pair : std::false_type
{ };

template <typename T, typename U>
struct is_pair<std::pair<T, U>> : std::true_type
{ };

// also tried this, but it didn't help
template <typename T, typename U>
struct is_pair<std::pair<const T, U>> : std::true_type
{ };

然后我在函数声明中使用 enable_if:

template<class ITR>
decltype(auto) do_stuff(
        std::enable_if<is_pair<typename ITR::value_type>::value, ITR> itr) {
    //access of itr->second ok.
}

但是,当我将此函数与映射迭代器一起使用时,我从 clang (Xcode 8.3) 收到以下错误消息:

Candidate template ignored: could not match 'enable_if' against '__map_iterator'

如果不匹配,没有进一步解释为什么启用。

检查 __map_iterator 的类型时,它看起来应该匹配 is_pair 检查。

最佳答案

最好将 std::enable_if 移动到另一个默认模板参数,如下所示:

template<class ITR, typename = typename std::enable_if<is_pair<typename ITR::value_type>::value, ITR>::type>
decltype(auto) do_stuff(ITR && itr) {
    //access of itr->second ok.
}

这不会阻止参数推导,因为 ITR && itr 现在是通用引用。

完整示例:

#include <type_traits>
#include <utility>
#include <map>

template <typename>
struct is_pair : std::false_type
{ };

template <typename T, typename U>
struct is_pair<std::pair<T, U>> : std::true_type
{ };


template<class ITR, typename = typename std::enable_if<is_pair<typename ITR::value_type>::value, ITR>::type>
decltype(auto) do_stuff(ITR && itr) {
    //access of itr->second ok.
}

int main()
{
    std::map<int, int> foo{
        { 1, 2 },
        { 3, 4 },
    };

    do_stuff(foo.begin());
    return 0;
}

Live on gcc.godbolt.org

关于c++ - enable_if 检查迭代器的值类型是否是一对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43992510/

相关文章:

c++ - 在模板类中使用 unordered_map 时出现编译器错误

c++ - 使用 epoll 的套接字服务器在断开连接时给出未知字节

c++ - 静态模板化 constexpr 嵌套类成员

c++ - 根据标准,这个 constexpr offset_of 的定义是否正确?

c++ - 为什么以 std::placeholders::_1 而不是 _0 开头?

c++ - 在子字段上使用 std::forward

c++ - 将txt文件保存为变量名

c++ - 在带有 static_assert 的命名空间中使用 constexpr 会出错

c++ - 代码不应该打印 "1 1"而不是 "4 4"吗?

c++ - 理解 std::function 的晦涩模板参数