重载STL函数

问题描述 投票:0回答:2

我有这样的代码:

   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则没有。谢谢。

c++ stl overloading
2个回答
4
投票

您不能在类定义之外为类的成员函数声明其他重载。该语言不提供语法。由于您无法修改标准库头文件中的类定义,因此也不能向其添加其他重载。


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>{});
}

0
投票

关于另一个问题-有关置换,即您希望集合在寻找置换时找到{1,2,3}的迭代器。


0
投票

就像@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);

-1
投票

我不认为C ++赋予您这样做的权利。有关更多信息,您可以根据需要使用此answer。希望对您有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.