在向量中读写不同类型

Posted

技术标签:

【中文标题】在向量中读写不同类型【英文标题】:Read and write different types in vector 【发布时间】:2017-03-24 18:48:19 【问题描述】:

我怎样才能在一个向量中打包几种不同的原始数据类型以及字符串来检查内容呢? (在 Java 中,这是通过 Object [] objects = 1.0, "Hello", - 42, 'b' 进行的)

任务如下: 给定以下数组:[3.0,42, "Monkey", 7.2, b]

这个数组将被传递给在控制台上输出数组内容的方法。如果是string,则字符串的每个字母都应作为ASCII值添加到同一个变量中,最后在控制台上以int的形式返回。跟char一模一样。

从今天开始,当我创建vector 时,我就知道了std::vector<double> numbers = 1.0,2.0; 如何编写函数以及如何访问索引numbers[i]; 以及向量的长度numbers.size()

我现在该如何解决这个问题?因为不幸的是,我没有找到针对向量中多种类型的简单

提前致谢:)

【问题讨论】:

Stack Overflow 是一个英文网站。请将您的帖子编辑成英文。 您可以使用std::any,但请记住,C++ 不会像 Java 那样存储反射类型信息,因此在运行时恢复这些信息会很棘手。 用谷歌翻译自动翻译。 @JohannesSchaub-litb:把你肮脏的爱情社区带回你的裸体海滩:-) 好的,我一会儿翻译一下 【参考方案1】:

C++ 不像 Java 那样进行类型擦除。要创建异构容器(这是您尝试做的技术术语),您需要广泛使用 std::anystd::variant,它们是 C++17 引入的新类。

std::vector<std::any> values1.0, "Hello", -42, 'b';
for(auto & any : values) 
    int * i;
    if(val = std::any_cast<int>(&any)) std::cout << "int: " << *i << std::endl;
    const char ** s;
    if(s = std::any_cast<const char *>(&any)) std::cout << "string-literal: " << *s << std::endl;
    double * d;
    if(d = std::any_cast<double>(&any)) std::cout << "double: " << *d << std::endl;
    char * c;
    if(c = std::any_cast<char>(&any)) std::cout << "char: " << *c << std::endl;

请注意该代码有多么混乱。尤其是因为许多人希望将"hello" 存储为std::string 对象,但除非用户明确指定它,否则这是无法做到的:

std::vector<std::any> values1.0, std::string"Hello", -42, 'b';

无论如何,我个人的意见是使用std::variant 会更合适,因为您可以更清楚地了解容器的使用方式,并且可以避免与std::any:

typedef std::variant<std::string, char, double, int> my_variant;

struct visitor 
    void operator()(std::string const& v) const 
        std::cout << "std::string: " << v<< std::endl;
    
    void operator()(double const& v) const 
        std::cout << "double: " << v << std::endl;
    
    void operator()(int const& v) const 
        std::cout << "int: " << v << std::endl;
    
    void operator()(char const& v) const 
        std::cout << "char: " << v << std::endl;
    
;

int main() 
    std::vector<my_variant> values1.0, "Hello", -42, 'b';
    for(my_variant & variant : values) 
        std::visit(visitor, variant);
    
    return 0;

如果我们不需要知道类型,我们甚至可以使用auto lambdas 使变体版本更简单:

typedef std::variant<std::string, char, double, int> my_variant;

int main() 
    std::vector<my_variant> values1.0, "Hello", -42, 'b';
    for(my_variant & variant : values) 
        std::visit(
            [](auto const& val) std::cout << "Some unknown type: " << val << std::endl;, 
            variant
        );
    
    return 0;

我没有通过我的编译器运行它,但这应该可以很好地了解如何在 C++ 中完成此类任务。

如果您无法访问 C++17,则可以使用 boost.anyboost.variant,我有理由确定它们都是标头-only 库,因此很容易导入到您的项目中。

【讨论】:

@IIIOE 如果对您有帮助,请确保投票并接受答案。 =)

以上是关于在向量中读写不同类型的主要内容,如果未能解决你的问题,请参考以下文章

如何使用一次广播在 MPI 中传输不同类型的向量

用于处理基于参数的不同数组类型的 C 向量

根据另一个不同大小和类型的向量对点向量进行排序

访问和修改包含具有不同变量类型的对象的 C++ 向量

将不同类型的向量传递给模板函数

jdbc 读写 blob 类型有哪些方式?