Boost Variant复制语义

3

我想知道boost variant的复制语义是什么。我已经检查了源代码,但对我来说有点难以理解,因此我想知道,在示例代码中,如果我的getVal(name)函数在返回时是否会复制底层向量?如果是这样,我应该将其更改为返回引用(&)吗?

using Val = boost::variant<std::vector<int>, std::vector<std::string>>;

Val getVal(std::string& name) {
 return map[name];// where map is std::map<std::string, Val>
}

如果你要更改它,那么它应该是一个常量引用。 - Deduplicator
1个回答

2

是的,你的getVal返回整个向量的副本(包括所有元素字符串的副本,例如)。

是的,返回一个引用可以解决这个问题。


注意,你也可以有一个存储引用的变体。在这种情况下,通过“按值”返回它仍然具有与返回引用相同的语义:

using Ref = variant<std::vector<int>&, std::vector<std::string>&>;

Ref getVal(std::string& name) {
   return map[name]; // where map is std::map<std::string, Val>
}

完整的示例,包括将Ref转换为Val(反之亦然)所需的必要机制:

在 Coliru 上实时运行

#include <boost/variant.hpp>
#include <map>
#include <vector>
#include <string>


using Val = boost::variant<std::vector<int>, std::vector<std::string>>;
using Ref = boost::variant<std::vector<int>&, std::vector<std::string>& >;

std::map<std::string, Val> map {
    { "first", std::vector<int> { 1,2,3,4 } },
    { "2nd",   std::vector<std::string> { "five", "six", "seven", "eight" } }
};

namespace { // detail
    template <typename T>
    struct implicit_convert : boost::static_visitor<T> {
        template <typename U> T operator()(U&& u) const { return std::forward<U>(u); }
    };
}

Ref getVal(std::string& name) {
    return boost::apply_visitor(implicit_convert<Ref>(), map[name]);
}

#include <iostream>

int main() {
    for (auto i : boost::get<std::vector<int>         >(map["first"])) std::cout << i << " ";
    for (auto i : boost::get<std::vector<std::string> >(map["2nd"]))   std::cout << i << " ";
}

输出:

1 2 3 4 five six seven eight 

在没有复制任何向量的情况下


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接