c++ - 使用 C++20 在编译时检查容器中是否存在重复元素

标签 c++ c++20 std-ranges

在 C++20 之前执行此操作的一种简单方法是执行嵌套循环:

template<typename Container>
constexpr bool has_duplicate(Container&& container)
{
    for (auto it1 = container.cbegin(); it1 != container.cend(); ++it1)
        for(auto it2 = container.cbegin(); it2 != it1; ++it2)
            if (*it1 == *it2)
                return 1;
    return 0;
}

通过在基于范围的 for 循环中添加 init 语句,并引入 ranges::subrange,我相信这个函数可以用基于范围的 for 循环重写:

template<std::ranges::input_range Container>
constexpr bool has_duplicate(Container&& container)
{
    for(auto it = container.cbegin(); const auto& obj1 : container)
        for(const auto& obj2 : std::ranges::subrange(container.cbegin(), it++))
            if(obj1 == obj2) 
                return 1;
    return 0;
}

虽然它在 gcc 上运行良好,但它无法用 clang 编译,除非我用 libc++ 手动设置它:https://godbolt.org/z/KM4a9zazs ,出现以下错误:

/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/iterator_concepts.h:982:13: error: no matching function for call to '__begin'
        = decltype(ranges::__cust_access::__begin(std::declval<_Tp&>()));
  • 是我做错了什么,还是它发出了响声?

我也试过:

template<std::ranges::input_range Container>
constexpr bool has_duplicate(Container&& container)
{
    for(auto index = 0ull; const auto& obj1 : container)
        for(const auto& obj2 : container | std::ranges::views::take(index++))
            if(obj1 == obj2) return 1;
    return 0;
}

gcc 再一次没有问题,但 clang 对任何一个库都失败了。

最佳答案

Godbolt 默认使用 libstdc++,即使在使用 Clang 编译时也是如此,这有点令人困惑。

Clang 是否真的应该完全支持链接到 libstdc++,我不能说,但是例如以下 Clang 错误报告强调了相同的问题:

错误报告中的最小示例:

#include <ranges>

void foo() {
    std::ranges::iota_view iota(2, 10);
    iota.begin(); 
}

error: no matching function for call to '__begin'

关于c++ - 使用 C++20 在编译时检查容器中是否存在重复元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69395803/

相关文章:

c++ - 是否有一种算法可以通过多组平行线段构建矩形

c++ - Qt moc 在头文件中实现?

c++ - C++11 中的 constexpr if-then-else

c++ - MacOS std::chrono::clock_cast 未找到

c++ - [[不太可能]]可以用循环吗?

c++ - 编译器不同意接受此 View ::keys 代码

c++ - 每当传递左值时存储一个 const 引用,并在传递右值时存储一个拷贝

c++ - 如何将智能迭代器传递给接受经典迭代器的函数?

c++ - 为什么我不能将这个转换后的 directory_iterator 插入到一个 vector 中?

c++ - 用户定义的容器不适用于 std::ranges