c++ - C++ 编译器如何扩展模板 <> 代码以及它如何影响相同的速度?

标签 c++ list templates pointers

我不太了解模板以及编译器如何处理它们。

需要一些 std::vector<< SomeType * >>* lpVars 的通用包装器;当我删除 lpVars 时,它能够对该 vector 中包含的所有项目执行删除。类似于 C# 的 List<>(通用列表类)。 所以我去找模板写了这样的东西:

template<class T>
class ListPtr
{
public:
  std::vector<T*> items;
  ListPtr()
  { }
  ~ListPtr()
  {
    size_t count = items.size();
    for(size_t i=0; i<count; i++)
    {
      T* item = items[i];
      delete item;
    }
    items.clear();
  }
  inline const int count() const
  {
    return (int)items.size();
  }
  inline T* operator[](size_t index) const
  {
    return items[index];
  }
  inline void Add(T* item)
  {
    items.push_back(item);
  }
};

稍后我将全局类型列表声明为:

class SomeType1List : public ListPtr<SomeType1> {};
class SomeType2List : public ListPtr<SomeType2> {};
...
class SomeTypeNList : public ListPtr<SomeTypeN> {};

这是我对主题感兴趣的第一部分:

(1) 这些类 SomeType1List、SomeType1List、...、SomeTypeNList 是否已完全预处理为模板代码,并为每个声明(SomeType1、SomeType2、...、SomeTypeN)替换了 T 模板类型,例如没有模板(是完全声明的类),或者编译器在这里执行其他一些魔法?

(2) 如果编译器执行一些其他魔法,我应该如何定义编译器将编译它们的类型,因为它们是完全声明的类?


为了更准确的解释上面代码的用法:

这个列表实例被初始化,并从如下函数返回:

SomeType1List* GetItems()
{
  SomeType1List* items = new SomeType1List();
  for(int i=0; i<1000; i++)
  {
    SomeType1* item = new SomeType1();
    // feed item with some data
    items->Add(item);
  }
  return items;
}

并用在代码的其他部分,如下所示:

SomeType1List* items = GetItems();
int count = items->count();
for(int i=0; i<count; i++)
{
  SomeType1* item = items[i];
  // do something with item;
}
delete items; // all memory occupied by items released after this line

第二部分我对主题的兴趣:

(3) 是否可以仅使用标准类(无 boost 或类似 sdk)以不同方式编写?目标是速度,但要保持代码干净易读。所以这个问题是有没有更好的方法来完成所有这些?

最佳答案

  1. 这里没有魔法

  2. 您可以使用 std::vector<std::unique_ptr<T>> (C++11) 或 std::vector<std::auto_ptr<T>> (有点过时了)

例子:

#include <iostream>
#include <memory>
#include <vector>

class T
{
private:
    unsigned int _i;

public: 
    void print() const
    {
        std::cout << "Print: " << _i << std::endl;
    }

    T(unsigned int i)
    {
        _i = i;

        std::cout << "Constructor! " << _i << std::endl;
    }

    ~T()
    {
        std::cout << "Destructor! " << _i << std::endl;
    }
};

std::vector<std::unique_ptr<T>>* createStuff()
{
    auto output = new std::vector<std::unique_ptr<T>>;

    for(unsigned int i = 0; i < 5; i++)
    {
        output->emplace_back(new T(i));
    }

    return output;
}

int main()
{
    std::cout << "Begin!" << std::endl;

    auto stuff = createStuff();

    for(std::unique_ptr<T> const& thing : *stuff)
    {
        thing->print();
    }

    delete stuff;

    std::cout << "End!" << std::endl;

    return 0;
}

输出:

Begin!
Constructor! 0
Constructor! 1
Constructor! 2
Constructor! 3
Constructor! 4
Print: 0
Print: 1
Print: 2
Print: 3
Print: 4
Destructor! 0
Destructor! 1
Destructor! 2
Destructor! 3
Destructor! 4
End!

关于c++ - C++ 编译器如何扩展模板 <> 代码以及它如何影响相同的速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21070333/

相关文章:

c++ - template 模板参数场景

c++ - 还有另一种使用stringstream的方法吗?

c++ - 有没有更简洁的方法来做到这一点? C++ 中频

c++ - 显式模板函数和方法特化

python - (单行)连接列表列表的命令,其中内部列表由空格连接,外部列表由 '\n' 连接

c++ - 从基类到派生类的静态转换

c++ - QComboBox 放置位置正在移动

python - 确定列表中的所有元素是否都存在并且在另一个列表中的顺序相同

java - 如何访问Java数组中的第一列数据并分配给另一个变量?

c++ - 当链接器可以使用显式特化时,所有编译器都会忽略生成的模板代码吗?