简体   繁体   English

C ++编译器如何扩展template <>代码,并且如何影响它们的速度?

[英]How c++ compilers extend template<> code and how does it affect speed of same?

I am little lost with templates, and how compiler processes them. 我对模板以及编译器如何处理它们几乎不知所措。

Needed some generic wrapper for std::vector<< SomeType * >>* lpVars; 需要std :: vector << SomeType * >> * lpVars的通用包装器; that is capable of performing delete on all items contained inside that vector when I delete lpVars. 当我删除lpVars时,能够对该向量中包含的所有项目执行删除操作。 Something similar to the C#'s List<> (generic list class). 与C#的List <>(通用列表类)相似。 So I went for templates and wrote something like this: 所以我去了模板,并写了这样的东西:

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

later on I declared global type lists like: 后来我声明了全局类型列表,例如:

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

Here is the first part of my interest on subject: 这是我对主题感兴趣的第一部分:

(1) Are this classes SomeType1List, SomeType1List, ..., SomeTypeNList fully preprocessed to templates code with replaced T template type for each declaration (SomeType1, SomeType2, ..., SomeTypeN) like there is no template (are fully declared classes), or compiler performs some other magic here? (1)是否像没有模板(完全声明的类)那样,对每个声明(SomeType1,SomeType2,...,SomeTypeN)的类SomeType1List,SomeType1List,...,SomeTypeNList进行了充分预处理,以替换了T模板类型的模板代码,还是编译器在这里执行其他功能?

(2) And if compiler performs some other magic, how should I define this types that compiler would compile them as they are fully declared classes? (2)如果编译器执行了其他魔术,那么我应该如何定义这种类型,以便它们在完全声明的类中被编译?


To explain usage of above code more precise: 为了更精确地解释上述代码的用法:

this list instances are initialized, and returned from functions like following one: 此列表实例已初始化,并从如下函数返回:

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

and used in other parts of code like this: 并在其他类似的代码部分中使用:

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

Second part of my interest on subject: 我对主题的兴趣的第二部分:

(3) Could this be written differently using only standard classes (no boost or similar sdks)? (3)是否可以仅使用标准类(不使用boost或类似的SDK)以不同的方式编写? goal is speed but to keep code clean and easy to read. 目标是速度,但要保持代码的清洁和易于阅读。 So this question would be is there any better way to do all of this? 因此,这个问题是否有更好的方法来完成所有这些工作?

  1. Yes

  2. No magic here 这里没有魔术

  3. You can use std::vector<std::unique_ptr<T>> (C++11) or std::vector<std::auto_ptr<T>> (kind of deprecated) 您可以使用std::vector<std::unique_ptr<T>> (C ++ 11)或std::vector<std::auto_ptr<T>> (不推荐使用)

Example: 例:

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

Output: 输出:

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!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM