我有这样的代码:
set<array<int, 3>> s;
int ar[3] = {1,2,3};
s.insert(ar);
auto it = s.find(ar);
以及IDE的消息,即no instance of overloaded function insert/find
。如果我使用std::array
没问题,::insert
和::find
的工作方式相同。但是,如果我想使用这些C数组T[N]
或set中具有std::array
的查找函数该怎么办,如果三个元素中的两个相等,则应返回迭代器。否则,如果set::insert
是存在的排列,则不会插入新数组,我的意思是s.insert({1,2,3})
-已经添加,s.insert({3,2,1})
-在{1,2,3}
上返回迭代器。
问题是如何重载STD函数?不在此代码中,而是一般而言?欢迎任何链接或真实代码示例。对于经验丰富的程序员来说,这可能是一个非常简单的问题),但是有很多运算符重载的示例,但对于STL则没有。谢谢。
您不能在类定义之外为类的成员函数声明其他重载。该语言不提供语法。由于您无法修改标准库头文件中的类定义,因此也不能向其添加其他重载。
std
命名空间中的自由函数可能不会被重载。它具有语法(与任何自由函数重载的工作方式相同),但是这样做会导致未定义的行为,因为标准中明确禁止使用它,请参见[namespace.std]/1。
通常(例外情况适用)是为std
命名空间中的实体定义模板专业化
[在std
名称空间内使用特殊化的常见示例是std::hash
,用作无序关联容器中的哈希函数:
struct my_type { //... }; namespace std { template<> struct hash<my_type> { auto operator()(my_type const& x) const noexcept { //... } }; }
但是如果将
my_type
替换为int*
,int[3]
或std::array<int, 3>
或类似的东西,即使这样的事情也是不允许的,因为不依赖于用户声明的类型。
如果要从内置数组中创建std::array
,则可以在C ++ 20中使用std::to_array
:
set<array<int, 3>> s; int ar[3] = {1,2,3}; s.insert(std::to_array(ar)); auto it = s.find(std::to_array(ar));
在C ++ 20之前,您可能具有在
std::experimental::to_array
中作为#include<experimental/array>
使用的功能,或者您可以自己定义(从cppreference.com;需要#include<type_traits>
,#include<utility>
和#include<cstddef>
):
namespace detail {
template <class T, std::size_t N, std::size_t... I>
constexpr std::array<std::remove_cv_t<T>, N>
to_array_impl(T (&a)[N], std::index_sequence<I...>)
{
return { {a[I]...} };
}
}
template <class T, std::size_t N>
constexpr std::array<std::remove_cv_t<T>, N> to_array(T (&a)[N])
{
return detail::to_array_impl(a, std::make_index_sequence<N>{});
}
关于另一个问题-有关置换,即您希望集合在寻找置换时找到{1,2,3}
的迭代器。
就像@walnut所说的那样,您不能在类定义之外为该类的成员函数声明其他重载。除了封装您自己的int <3>类之外,还有另一种解决方法-运算符<
set<array<int, 3>>& operator << (set<array<int, 3>>& s, int ar[3]) { array<int,3> ar2 { ar[0], ar[1], ar[2] }; s.insert(ar2); return s; }
看起来很奇怪,但是易于使用。
现在您可以执行此操作
set<array<int, 3>> s; int ar[3] = {1,2,3}; s << ar;
但是,如果要在针对数组的int [3]集合中使用一堆函数,最好定义自己的类/结构。
template <class T, int arsize> struct MyFixedArray { T ar[arsize]; MyFixedArray(T _ar[arsize]) { for (int i = 0; i < arsize; ++i) ar[i] = _ar[i]; }; operator array<T, arsize>() const { array<T, arsize> _ar; for (int i = 0; i < arsize; ++i) _ar[i] = ar[i]; return _ar; }; };
现在您可以在任何地方自由使用它
MyFixedArray<int, 3> myar(ar);
s.insert(myar);
auto it = s.find(myar);
我不认为C ++赋予您这样做的权利。有关更多信息,您可以根据需要使用此answer。希望对您有帮助。