【问题标题】:C++ Iterate Over All Generics At OnceC++ 一次迭代所有泛型
【发布时间】:2019-07-19 11:27:50
【问题描述】:

以下代码:

#include <cstdio>
#include <iostream>
#include <vector>

template<class type>
struct A {
    type i;
    A(type j){
        i = j;
    }
};

template<class type>
std::vector<A<type>*> ve;

int main(int argc, char** args){
    ve<int>.push_back(new A<int>(1));
    ve<int>.push_back(new A<int>(2));
    ve<char>.push_back(new A<char>('a'));
    ve<char>.push_back(new A<char>('b'));
    for(unsigned int i = 0; i < ve<int>.size(); i++)
        std::cout << ve<int>[i]->i << std::endl;
    for(unsigned int i = 0; i < ve<char>.size(); i++)
        std::cout << ve<char>[i]->i << std::endl;
    return 0;
}

输出:

1
2
a
b


如何重现相同的输出,但只有一个 for 循环?

是的,我知道预处理器在这里制作了两个不同的向量。
告诉我如何组合它们或告诉我一个通用的 for 循环。

【问题讨论】:

  • 如果你的目的是学习 C++,你应该忘记你所知道的关于 Java 的一切。 C++ 不是 Java,尽管语法相似,但 C++ 以根本不同的方式工作。上面的代码中没有任何内容——例如——要求任何内容为newed。例如,在 C++ 中,对象不是由new 关键字创建的new 键盘完全不同。您刚刚在上面创建了一堆内存泄漏。在尝试学习模板等高级概念之前,最好花一些时间学习 C++ 基础知识,否则只会让你感到困惑。
  • “这里的所有内存都会在程序终止时自动释放”不,你把它全部泄露了。
  • “是的,我知道预处理器在这里制作了两个不同的向量。”它没。预处理器参与模板初始化(它根本不理解模板)。
  • @LightnessRacesinOrbit 您声称操作系统不会在 exe 终止时回收该内存?
  • @PhilM 不,但它本身并没有“发布”。添加一些析构函数,您就会遇到问题。永远释放你的记忆。

标签: c++ templates iterator containers


【解决方案1】:

解决方案:

#include <cstdio>
#include <iostream>
#include <vector>

struct B {
    virtual void memberOut(){}
};

template<class type>
struct A : B{
    type i;
    A(type j):B(){
        i = j;
    }
    void memberOut(){
        std::cout << i << std::endl;
    }
};

std::vector<B*> ve;

int main(int argc, char** args){
    ve.push_back(new A<int>(1));
    ve.push_back(new A<int>(2));
    ve.push_back(new A<char>('a'));
    ve.push_back(new A<char>('b'));
    for(unsigned int i = 0; i < ve.size(); i++)
        ve[i]->memberOut();
    return 0;
}

注意事项:
要么将其保留为两个容器,要么制作虚拟功能。两者都有其用途。
对变量使用模板只会生成两个变量。
您还可以保存另一个 type_index 向量并使用 typeid 来记住 void 指针稍后是什么指针类型,但这只是虚函数的草率版本。示例:

std::vector<void*> values
std::vector<std::type_index> types
if(types[i]==typeid(A<int>*))


旁注:
编写 cmets 时尽量不要偏离基础。
cmets 的目标是让问题得到解答,而不是辩论。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    相关资源
    最近更新 更多