在向量中读写不同的类型

时间:2017-03-24 18:48:20

标签: c++ c arrays vector

如何在向量中包含几种不同的原始数据类型以及字符串来检查内容呢? (在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];以及向量{{1}的长度}。

我现在如何解决这个问题?因为我遗憾地发现没有简单的&lt; - 解决方案中的多个类型。

提前致谢:)

1 个答案:

答案 0 :(得分:0)

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

std::vector<std::any> values{1.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> values{1.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> values{1.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> values{1.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.any boost.variant ,我相信这两个标题都是标题 - 只有库,因此很容易导入您的项目。