【问题标题】:How to refactoring this code with STL?如何用 STL 重构这段代码?
【发布时间】:2016-04-18 14:01:02
【问题描述】:

这是我的练习代码.. 书籍问题正在将此代码重构为模板(使用 STL)

我找到了一些书和谷歌,但我不明白

你能给我举个例子吗?

int SumInt(const int* a, int count) {
     int result = 0;
     for (int i = 0; i < count; ++i) {
     result += a[i];
     }
     return result;
}

float SumFloat(const float* a, int count) {
    float result = 0;
    for (int i = 0; i < count; ++i) {
    result += a[i];
    }
    return result;
}
void main() {
    int intVals[] = {0, 1, 2};
    float floatVals[] = {0.F, 1.F, 2.F};

    int intTotal = SumInt(intVals, 3);
    float floatTotal = SumFloat(floatVals, 3);

 .... 
}

【问题讨论】:

  • 首先用std::vector替换原始数组:std::vector&lt;int&gt; intVals {0, 1, 2};std::vector&lt;float&gt; floatVals = {0.F, 1.F, 2.F};
  • 如果你的书告诉你void main,那它不是一本 C++ 书。

标签: c++ templates stl


【解决方案1】:

你可以使用std::accumulate:

int intTotal = std::accumulate(std::begin(intVals), std::end(intVals), 0);
float floatTotal = std::accumulate(std::begin(floatVals), std::end(floatVals), 0.0F);

【讨论】:

    【解决方案2】:

    在此示例中,您可以将SumInt 和SumFloat 替换为模板Sum,如下所示:

    template <typename T> int Sum(const T* a, int count) {
         T result = 0;
         for (int i = 0; i < count; ++i) {
             result += a[i];
         }
         return result;
    }
    

    然后在你的main(),你可以打电话

    int intTotal = Sum(intVals, 3);
    float floatTotal = Sum(floatVals, 3);
    

    编译器将调用int 或float 版本,具体取决于您提供给Sum 的参数类型。

    【讨论】:

    • 基本上这个想法是用通用的数据类型替换特定的数据类型(在这种情况下为int 或float)。人们经常使用“T”作为泛型类型的符号。
    【解决方案3】:

    一个涉及模板参数和使用STL(c++标准库)的实现:

    #include <iostream>
    #include <vector>
    #include <cstddef> 
    
    template <typename T>
    T Sum(const std::vector<T>& a) {
         T result = 0;
         for (size_t i = 0; i < a.size(); ++i) {
             result += a[i];
         }
         return result;
    }
    
    
    int main() {
        std::vector<int> intVals {0, 1, 2};
        std::vector<float> floatVals {0.F, 1.F, 2.F};
    
        int intTotal = Sum(intVals);
        float floatTotal = Sum(floatVals);
    
        std::cout << intTotal << std::endl;
        std::cout << floatTotal << std::endl;
    }
    

    见Live Demo

    【讨论】:

    • 你真的需要指定&lt;int&gt;还是编译器可以推断出向量intVals是由int组成的?
    【解决方案4】:

    我们开始(您的 sum(...) 函数的简单模板):

    template <typename T>
    T sum(const T* a, size_t count) {
        T result = 0;
        for (size_t i = 0; i < count; ++i) {
            result += a[i];
        }
        return result;
    }
    
    int main() {
        const int intVals[] = { 0, 1, 2 };
        const float floatVals[] = { 0.F, 1.F, 2.F };
    
        const int intTotal = sum(intVals, 3);
        const float floatTotal = sum(floatVals, 3);
    
        std::cout << "float total: " << intTotal << std::endl;
        std::cout << "int total: " << floatTotal << std::endl;
    }
    

    我喜欢std::accumulate,不过:

    int main() {
        const auto intVals = { 0, 1, 2 };
        const auto floatVals = { 0.F, 1.F, 2.F };
    
        const auto intTotal = std::accumulate(intVals.begin(), intVals.end(), 0);
        const auto floatTotal = std::accumulate(floatVals.begin(), floatVals.end(), 0.0F);
    
        std::cout << "float total: " << intTotal << std::endl;
        std::cout << "int total: " << floatTotal << std::endl;
    }
    

    【讨论】:

      【解决方案5】:

      您使用这样的模板。另请阅读:http://www.cplusplus.com/doc/oldtutorial/templates/

      template<typename T>
      T doSomething(const T a, int count)
      {
        // do your stuff
      
      }
      

      你可以这样使用它:

      int w = 1;
      doSomething(w, 1);
      

      在这种情况下,您将 T 替换为 int

      【讨论】:

      • 在这种情况下您不需要指定&lt;int&gt;。编译器可以推导出来。只需致电doSomething(1, 1)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-15
      相关资源
      最近更新 更多