2009-07-06 64 views
-3

我正在組織一個演示文稿,以展示我認爲C#可能提供的超過C++的一些生產力增益。我用C#編寫了一些代碼,我想將它轉換爲C++。我沒有時間或最新的C++做轉換正義,因此張貼在這裏。幫助 - 請將此LINQ示例轉換爲C++

代碼轉換:

using System.Collections.Generic; 
using System.Drawing; 
using System.Linq; 

namespace LinqTest 
{ 
    public class Vehicle 
    { 
     public int Id { get; set; } 
     public Color Colour { get; set; } 
    } 

    public class Tyre 
    { 
     public int Id { get; set; } 
     public int BikeId { get; set; } 
     public int Size { get; set; } 
     public string Brand { get; set; } 
    } 

    public class Car : Vehicle {} 

    public class Bike : Vehicle {} 

    public class Example 
    { 
     private readonly IList<Car> cars; 
     private readonly IList<Tyre> bikeTyres; 
     private readonly IList<Bike> bikes; 

     public Example() 
     { 
      cars = new List<Car> 
         { 
          new Car {Id = 0, Colour = Color.Red}, 
          new Car {Id = 1, Colour = Color.Blue}, 
          new Car {Id = 2, Colour = Color.Green}, 
          new Car {Id = 3, Colour = Color.Green} 
         }; 

      bikeTyres = new List<Tyre> 
          { 
           new Tyre {Id = 0, BikeId = 0, Brand = "TyreCo1", Size = 23}, 
           new Tyre {Id = 1, BikeId = 0, Brand = "TyreCo1", Size = 23}, 
           new Tyre {Id = 2, BikeId = 1, Brand = "TyreCo2", Size = 30}, 
           new Tyre {Id = 3, BikeId = 1, Brand = "TyreCo2", Size = 30}, 
           new Tyre {Id = 4, BikeId = 2, Brand = "TyreCo3", Size = 23}, 
           new Tyre {Id = 5, BikeId = 2, Brand = "TyreCo3", Size = 23} 
          }; 

      bikes = new List<Bike> 
         { 
          new Bike {Id = 0, Colour = Color.Red}, 
          new Bike {Id = 1, Colour = Color.Blue}, 
          new Bike {Id = 2, Colour = Color.Green} 
         }; 
     } 

     public IEnumerable<Vehicle> FindVehiclesByColour(Color colour) 
     { 
      var carVehicles = from car in cars 
          where car.Colour == colour 
          select car as Vehicle; 

      var bikeVehicles = from bike in bikes 
           where bike.Colour == colour 
           select bike as Vehicle; 

      return carVehicles.Union(bikeVehicles); 
     } 


     public IEnumerable<Bike> FindBikesByTyreSize(int size) 
     { 
      return (from bike in bikes 
        join tyre in bikeTyres on bike.Id equals tyre.BikeId 
        where tyre.Size == size 
        select bike).Distinct(); 
     } 
    } 
} 

在此先感謝。

+0

我想添加一個賞金,因爲這個問題是相當複雜的,但似乎我不能馬上離開。 – ng5000 2009-07-06 09:46:02

+0

爲什麼倒票?對我來說這似乎是一個合理的要求,我們當然會增加關於SO的知識。至少將我指向一些C++類型/方法。 – ng5000 2009-07-06 09:52:02

回答

3

我會爲你做這件事,但記錄這絕對是一個壞的'問題'。這是更多的工作要求,這就是爲什麼我的答案是社區維基。這裏沒有回答問題。

#include <algorithm> 
#include <list> 
#include <string> 

namespace LinqTest 
{ 
    // C++ does not specificy a standard GUI library. 
    // This is a small hack to make the code work below. 
    // In a real solution, one would probably have a real 
    // Color class that stores the red, green, and blue 
    // components of the colors and provides operations 
    // to act upon colors. 
    struct Color 
    { 
     static const int Red = 0; 
     static const int Green = 1; 
     static const int Blue = 2; 

     Color(void) : 
     value(0) 
     { 
     } 

     Color(int color) : 
     value(color) 
     { 
     } 

     bool operator==(const Color& rhs) const 
     { 
      return value == rhs.value; 
     } 

     int value; 
    }; 

    struct Vehicle 
    { 
     Vehicle(void) : 
     Id(0) 
     { 
     } 

     Vehicle(int id, Color colour) : 
     Id(id), 
     Colour(colour) 
     { 
     } 

     bool operator==(const Vehicle& rhs) const 
     { 
      return Id == rhs.Id; 
     } 

     int Id; 
     Color Colour; 
    }; 

    struct Tyre 
    { 
     Tyre(void) : 
     Id(0), 
     BikeId(0), 
     Size(0) 
     { 
     } 

     Tyre(int id, int bikeId, int size, std::string brand) : 
     Id(id), 
     BikeId(bikeId), 
     Size(size), 
     Brand(brand) 
     { 
     } 

     int Id; 
     int BikeId; 
     int Size; 
     std::string Brand; 
    }; 

    struct Car : 
     public Vehicle 
    { 
     Car(void) 
     { 
     } 

     Car(int id, Color colour) : 
     Vehicle(id, colour) 
     { 
     } 
    }; 

    struct Bike : 
     public Vehicle 
    { 
     Bike(int id, Color colour) : 
     Vehicle(id, colour) 
     { 
     } 
    }; 

    class Example 
    { 
    // I put private up top to match yours, but most C++ 
    // programmers would prefer it on the bottom, justified 
    // by the fact users of the class don't care or want 
    // to see how the class works, they want to see how to 
    // use it. 
    private: 
     std::list<Car> cars; 
     std::list<Tyre> bikeTyres; 
     std::list<Bike> bikes; 

    public: 
     Example(void) 
     { 
      cars.push_back(Car(0, Color::Red)); 
      cars.push_back(Car(1, Color::Blue)); 
      cars.push_back(Car(2, Color::Green)); 
      cars.push_back(Car(3, Color::Green)); 

      bikeTyres.push_back(Tyre(0, 0, 23, "TyreCo1")); 
      bikeTyres.push_back(Tyre(1, 0, 23, "TyreCo1")); 
      bikeTyres.push_back(Tyre(2, 1, 30, "TyreCo2")); 
      bikeTyres.push_back(Tyre(3, 1, 30, "TyreCo2")); 
      bikeTyres.push_back(Tyre(4, 2, 23, "TyreCo3")); 
      bikeTyres.push_back(Tyre(5, 2, 23, "TyreCo3")); 

      bikes.push_back(Bike(0, Color::Red)); 
      bikes.push_back(Bike(1, Color::Blue)); 
      bikes.push_back(Bike(2, Color::Green)); 
     } 

     // I chose to return pointers to Vehicles to maintain any 
     // polymorphic behavior, since from what I understand C# 
     // would be returning references here. 
     std::list<Vehicle*> FindVehiclesByColour(Color colour) 
     { 
      typedef std::list<Car>::iterator car_iterator; 
      typedef std::list<Bike>::iterator bike_iterator; 

      std::list<Vehicle*> result; 

      for (car_iterator iter = cars.begin(); iter != cars.end(); ++iter) 
      { 
       if (iter->Colour == colour) 
       { 
        result.push_back(&(*iter)); 
       } 
      } 

      for (bike_iterator iter = bikes.begin(); iter != bikes.end(); ++iter) 
      { 
       if (iter->Colour == colour) 
       { 
        result.push_back(&(*iter)); 
       } 
      } 

      return result; 
     } 

     std::list<Bike*> FindBikesByTyreSize(int size) 
     { 
      typedef std::list<Tyre>::const_iterator tyre_iterator; 
      typedef std::list<Bike>::iterator bike_iterator; 

      std::list<Bike*> result; 

      for (tyre_iterator tyreIter = bikeTyres.begin(); tyreIter != bikeTyres.end(); ++tyreIter) 
      { 
       if (tyreIter->Size == size) 
       { 
        for (bike_iterator bikeIter = bikes.begin(); bikeIter != bikes.end(); ++bikeIter) 
        { 
         if (tyreIter->BikeId == bikeIter->Id) 
         { 
          result.push_back(&(*bikeIter)); 
         } 
        } 
       } 
      } 

      result.sort(); 
      result.unique(); 
      return result; 
     } 
    }; 
} 

注意裏面還有一些風格的東西,比如Example(void)Example()這是我自己的,並不一定代表其他C++程序員的風格。相關的,還有其他方法可以做到這一點,我的方式可能不是最好的。

缺少評論,我會添加他們,但我認爲他們只會阻礙,代碼很容易理解。這些都說,你顯然不太瞭解C++,所以說C#更有效率,甚至可能是真實的,很難認真對待你自己。此外,您在C#中執行的某些算法實際上可能效率很低,例如只存儲Tire自行車的ID,然後對匹配的Bike進行線性搜索。

2

我不想編輯其他的答案,因爲它似乎足夠清醒,但有一些小事情我會做不同的事情。所以這裏有一個稍微修改過的其他答案版本,它試圖稍微重複一點代碼。另外,我覺得使用堆分配對象對於原始的c#更加真實。

注意:公平地說,這忽略了所有的內存清理,但是如果使用了智能指針,它會很簡單。

#include <algorithm> 
#include <list> 
#include <string> 

namespace LinqTest { 

    template<typename In, typename Out, typename Pred> 
    Out copy_if(In first, In last, Out res, Pred Pr) { 
     while (first != last){ 
     if (Pr(*first)) 
      *res++ = *first; 
     ++first; 
     } 
     return res; 
    } 

    struct ColorMatch { 
     ColorMatch(Color c) : colour(c) { 
     } 

     bool operator()(const Vehicle *v) { 
      return v->Colour == colour; 
     } 

    private: 
     Color colour; 
    }; 

    struct IdMatch { 
     IdMatch(int id) : Id(id) { 
     } 

     bool operator()(const Bike *v) { 
      return v->Id == Id; 
     } 

    private: 
     int Id; 
    }; 

    // C++ does not specificy a standard GUI library. 
    // This is a small hack to make the code work below. 
    // In a real solution, one would probably have a real 
    // Color class that stores the red, green, and blue 
    // components of the colors and provides operations 
    // to act upon colors. 
    struct Color { 
     static const int Red = 0; 
     static const int Green = 1; 
     static const int Blue = 2; 

     Color() : value(0) { 
     } 

     Color(int color) : value(color) { 
     } 

     bool operator==(const Color& rhs) const { 
      return value == rhs.value; 
     } 

     int value; 
    }; 

    struct Vehicle { 
     Vehicle() : Id(0) { 
     } 

     Vehicle(int id, Color colour) : Id(id), Colour(colour) { 
     } 

     bool operator==(const Vehicle& rhs) const { 
      return Id == rhs.Id; 
     } 

     int Id; 
     Color Colour; 
    }; 

    struct Tyre { 
     Tyre() : Id(0), BikeId(0), Size(0) { 
     } 

     Tyre(int id, int bikeId, int size, std::string brand) : Id(id), BikeId(bikeId), Size(size), Brand(brand) { 
     } 

     int Id; 
     int BikeId; 
     int Size; 
     std::string Brand; 
    }; 

    struct Car : public Vehicle { 
     Car() { 
     } 

     Car(int id, Color colour) : Vehicle(id, colour) { 
     } 
    }; 

    struct Bike : public Vehicle { 
     Bike(int id, Color colour) : Vehicle(id, colour) { 
     } 
    }; 

    class Example { 
    // I put private up top to match yours, but most C++ 
    // programmers would prefer it on the bottom, justified 
    // by the fact users of the class don't care or want 
    // to see how the class works, they want to see how to 
    // use it. 
    private: 
     std::list<Car *> cars; 
     std::list<Tyre *> bikeTyres; 
     std::list<Bike *> bikes; 

    public: 
     Example() { 
       cars.push_back(new Car(0, Color::Red)); 
       cars.push_back(new Car(1, Color::Blue)); 
       cars.push_back(new Car(2, Color::Green)); 
       cars.push_back(new Car(3, Color::Green)); 

       bikeTyres.push_back(new Tyre(0, 0, 23, "TyreCo1")); 
       bikeTyres.push_back(new Tyre(1, 0, 23, "TyreCo1")); 
       bikeTyres.push_back(new Tyre(2, 1, 30, "TyreCo2")); 
       bikeTyres.push_back(new Tyre(3, 1, 30, "TyreCo2")); 
       bikeTyres.push_back(new Tyre(4, 2, 23, "TyreCo3")); 
       bikeTyres.push_back(new Tyre(5, 2, 23, "TyreCo3")); 

       bikes.push_back(new Bike(0, Color::Red)); 
       bikes.push_back(new Bike(1, Color::Blue)); 
       bikes.push_back(new Bike(2, Color::Green)); 
     } 

     // I chose to return pointers to Vehicles to maintain any 
     // polymorphic behavior, since from what I understand C# 
     // would be returning references here. 
     std::list<Vehicle*> FindVehiclesByColour(Color colour) { 
      copy_if(cars.begin(), cars.end(), std::back_inserter(result), ColorMatch(colour)); 
      copy_if(bikes.begin(), bikes.end(), std::back_inserter(result), ColorMatch(colour)); 
      return result; 
     } 

     std::list<Bike*> FindBikesByTyreSize(int size) { 
      typedef std::list<Tyre>::const_iterator tyre_iterator; 

      std::list<Bike*> result; 

      for (tyre_iterator tyreIter = bikeTyres.begin(); tyreIter != bikeTyres.end(); ++tyreIter) { 
       if (tyreIter->Size == size) { 
        copy_if(bikes.begin(), bikes.end(), std::back_inserter(result), IdMatch(bikeIter->Id)); 
       } 
      } 

      result.sort(); 
      result.unique(); 
      return result; 
     } 
    }; 
}