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

pftdvrlh  于 2022-12-30  发布在  其他
关注(0)|答案(2)|浏览(172)

例如,如果我想赋值

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

这种自定义分配是否可行?

ubbxdtey

ubbxdtey1#

看起来你需要的是将一个容器 transform 到另一个容器,这通常是通过命名合适的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
});
rxztt3cl

rxztt3cl2#

可以重载=以获得a = b;,并将所有元素second推送到a吗?
不能。除了std类型的重载操作符的其他问题之外,=只能作为成员函数实现。您不能向std::vector<int>添加成员。
可以重载=以获得a = b;,并将所有元素second推送到a吗?
可以。您不能为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分钟(注解应该只在代码本身无法清楚表达的时候才需要解释代码,这里不是这种情况)。

相关问题