c++ - boost 变体复制语义

标签 c++ boost boost-variant

我想知道 boost 变体的复制语义是什么。我已经检查了源代码,这让我有点莫名其妙,所以我想知道,在示例代码中,我的 getVal(name) 函数在返回时是否复制了底层 vector ?如果是这样,我是否应该将其更改为返回的引用 (&)?

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>
}

最佳答案

是的,您的 getVal 返回整个 vector 的拷贝(例如,包括所有元素字符串的拷贝)。

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


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

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(反之亦然)的必要机制的完整示例:

Live On 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 

没有任何 vector 被复制

关于c++ - boost 变体复制语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27863960/

相关文章:

c++ - shared_ptr : what's it used for

c++ - clion cmake 项目不编译 : dyld mach-o, 但为模拟器(不是 macOS)构建

c++ - 升压::变体 - "no matching function for call"

c++ - QT中使用QjsonDocument解析api数据

c++ - 预编译 header IntelliSense 错误

c++ - 哪个是更好的方法 - 将 `const reference` 与 `boost::shared_ptr<Class>` 存储为成员变量

c++ - 在 boost::variant 对象 vector 之后进行清理

c++ - boost ublas : rotate 2d vector

c++ - 将 Boost Spirit 解析器从 boost::variant 转换为 std::variant

c++ - 升压::变体; std::unique_ptr 和复制