标准库类上的自定义赋值运算符

Custom assignment operator on standard library classes

提问人:prestokeys 提问时间:12/30/2022 最后编辑:prestokeys 更新时间:12/30/2022 访问量:65

问:

例如,如果我想进行作业

std::vector<int> a;
std::vector<std::pair<std::string, int>> b;
a = b;  // a takes all the second components of the pairs in b

这样的自定义分配是否可行?

C++ 赋值运算符

评论

1赞 463035818_is_not_an_ai 12/30/2022
=不能是非会员:en.cppreference.com/w/cpp/language/operators
0赞 prestokeys 12/30/2022
我想要重载,因为我在很多地方都使用了 =,现在我已经更改了左向量操作数,我将不得不在我使用的 = 的任何地方放置必要的转换函数。

答:

6赞 Some programmer dude 12/30/2022 #1

您似乎想要的是将一个容器转换为另一个容器。这通常通过适当命名的 std::transform 标准函数来完成:

std::vector<int> a(b.size());  // Set as same size as the source vector

std::transform(begin(b), end(b), begin(a), [](auto const& pair)
{
    return pair.second;  // Use the second value of each pair from the source
});

评论

0赞 Mooing Duck 12/30/2022
我可能会选择而不是调整大小,但这是一般答案std::back_inserter
0赞 Some programmer dude 12/30/2022
@MooingDuck 这将导致数据的多次重新分配,最好在知道数据后设置大小。
1赞 Mooing Duck 12/30/2022
reserve然后。如果引发异常,调整大小会留下问题
2赞 463035818_is_not_an_ai 12/30/2022 #2

你能重载把所有元素推送到吗?=a = b;seconda

不。撇开类型重载运算符的其他问题不谈,只能作为成员函数实现。不能将成员添加到 。std=std::vector<int>


你能重载把所有元素推送到吗?=a = b;seconda

是的。不能重载 ,但可以重载其他类型:=std::vector

#include <vector>
#include <utility>
#include <string>


struct pick_second_vector_ref {
    std::vector<int>& t;
    template <typename Source>
    void operator=(const Source& s) {
        for (const auto& e : s) {
            t.push_back(e.second);
        }
    }
};

int main() {
    std::vector<int> a;
    std::vector<std::pair<std::string, int>> b {{"foo",42}};
    pick_second_vector_ref r{a};
    r = b;  // a takes all the second components of the pairs in b
}

但是,这只是为了说明当您的问题过于字面意思时会发生什么。通常,命名函数比执行意外操作的运算符重载要清晰得多。上面的内容应该看起来像这样:main

int main() {
    std::vector<int> a;
    std::vector<std::pair<std::string, int>> b {{"foo",42}};
    copy_second(a,b); // no comment needed here because the code 
                      // explains itself !!
}

...附言...

我在很多地方都使用了 =,现在我已经更改了左向量操作数,我将不得不在我使用的所有地方放置必要的变换函数。=

还行。去吧。更改代码。这将是简单的修复,因为代码中出现的所有错误都是编译器错误。请记住:代码只写一次,但读很多次。从长远来看,您花在修复上将节省 5 分钟,因为读者不必怀疑它实际上做了什么(只有当代码本身无法清楚地表达代码时,才需要注释来解释代码,这里的情况并非如此)。===