我正在整理一个演示文稿,以展示我认为C#可能比C ++提供的一些生产力提升。我在C#中编写了一些代码,我想将其转换为C ++。我没有时间或最新的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 :(得分: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#中执行的某些算法实际上可能效率非常低,例如只存储轮胎自行车的ID,然后对匹配的自行车进行线性搜索。
答案 1 :(得分: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;
}
};
}