Có thư viện LINQ cho C ++ không? [đóng cửa]


82

Có bất kỳ chuyển động bất khả tri Nền tảng nào (không phải CLI) để khiến LINQ sử dụng C ++ theo một cách nào đó không?

Ý tôi là một phần tuyệt vời của các khung máy chủ trên khắp thế giới chạy trên các phiên bản của UNIX và việc có quyền truy cập vào LINQ cho C ++ trên UNIX có lẽ sẽ khiến nhiều người hài lòng!


1
Ý bạn là đơn nguyên (IEnumerable <> và tập hợp các phương thức mở rộng trên đó)? Ý bạn là khía cạnh ngôn ngữ của nó? Ý bạn là LINQ-to-SQL?
yfeldblum 26/10/08

Vâng, phần LINQ-SQL là phần tôi thực sự muốn, nhưng điều đó phụ thuộc vào ngôn ngữ và monads của LINQ.
Robert Gould

2
Người đàn ông, đây là một câu hỏi thực sự hữu ích! Vui lòng không đóng những câu hỏi như thế này!
j00hi

vui lòng kiểm tra implimentation github.com/DevUtilsNet/linqcpp của tôi Tôi đã phân tích các triển khai khác và loại bỏ tất cả các lỗi không phù hợp với tôi.
antwoord

Câu trả lời:


34

Linq ++ của Hong Jiang có vẻ như là một khởi đầu tốt. Cú pháp của nó gần với Linq hơn nhiều so với CLinq. Linq của pfultz2 trông cũng thú vị, nhưng nó cần một trình biên dịch C ++ 11.


1
Đẹp. Phiên bản c ++ 11 có vẻ rất thú vị, ngay cả khi ví dụ hiểu thô của anh ấy nên sử dụng Phoenix để tránh "mã soạn sẵn".
KitsuneYMG

hmm, tôi không thấy chúng hỗ trợ cơ sở dữ liệu SQL.
Arne

21

Đây là giải pháp của tôi về thư viện mẫu C ++ LINQ.
Mã nguồn ở đây: Boolinq
Có rất nhiều thử nghiệm trên mỗi tính năng.
Tôi đang làm việc với nó ngay bây giờ.

Có ý kiến ​​gì không?
Có thể là lời khuyên?

CẬP NHẬT: dự án đã chuyển sang https://github.com/k06a/boolinq và hiện có phiên bản 2.0 với chỉ 700 dòng mã nguồn :)


Tôi không thể sử dụng boolinq với Qt 5.9.1 do lỗi biên dịch liên quan Q_FOREACH. Có lẽ là do Q_FOREACHbị loại bỏ dần dần.
Nikola Malešević

@ NikolaMalešević bạn có thể thử xác định ngay trước khi bao gồm boolinq.h: #define foreach for_eachsau đó sau bao gồm: #undef foreachvà sau đó bao gồm tiêu đề Qt.
k06a

1
Thực sự thích Boolinq! xin vui lòng thêm groupby
pingu

18

Microsoft vừa thông báo rằng họ đã xây dựng LINQ cho C và C ++. Tuy nhiên, vẫn chưa có sẵn.

Cập nhật 11/06/2012:

Microsoft Open Technologies, Inc. hiện đã phát hànhmã nguồn mở (Apache License 2.0) một số thư viện liên quan, bao gồm triển khai LINQ (Ix ++) và thư viện Reactive Extensions (Rx ++) mới.


8

http://cpplinq.codeplex.com/ là một triển khai rất tốt.
Từ tác giả:
Động lực cho CppLinq là cả boolinq và Native-RX dường như đều dựa trên toán tử "." để soạn các chức năng danh sách. Vấn đề là dấu "." là nó không thể bị quá tải trong C ++, điều này làm cho việc mở rộng các thư viện này bằng các chức năng do tôi thiết kế riêng. Đối với tôi, điều này là quan trọng. CppLinq dựa trên toán tử >> có thể quá tải do đó CppLinq có thể được mở rộng.


7

Bạn có thể xem qua PSade.Oven , một thư viện được tăng cường mạnh mẽ làm việc trên các dải STL và cung cấp nhiều hàm giống như LINQ.


khá thú vị, tôi sẽ xem nó khi có cơ hội, cảm ơn!
Robert Gould

7

Tôi đã viết một thư viện nhỏ cppLinq thực hiện lại IEnumerable <> và các toán tử LINQ của nó. Nó chỉ là một thử nghiệm; hiện tại nó chỉ hoạt động trên Windows (các coroutines được thực hiện với các sợi Win32) và chỉ xây dựng với Dev Preview của VS11 (nó sử dụng nhiều biểu thức lambda :-)).

Nó cho phép viết mã như thế này:

auto source = IEnumerable<int>::Range(0, 10);

auto it = source->Where([](int val) { return ((val % 2) == 0); })
                ->Select<double>([](int val) -> double { return (val * val); }));

foreach<double>(it, [](double& val){
    printf("%.2f\n", val);
});

7
Chuyển đổi một cách mù quáng C # sang C ++ sẽ không làm tốt bất kỳ ai. Tại sao bạn cần các giao diện? Nếu bạn loại bỏ những thứ đó, bạn sẽ loại bỏ tất cả những phân bổ vô ích đó và cả cú pháp poiner nữa. Và nếu bạn không thể, ít nhất hãy chuyển shared_ptrs thành unique_ptrs, vì cái sau có thể được chuyển thành cái trước, nhưng không phải ngược lại. Ngoài ra, phong cách khác biệt, bạn không cần -> doubleloại trả lại. Chỉ cần để các chuyển đổi ngầm thực hiện công việc của chúng.
Xeo

2
Cám ơn bạn đã góp ý. Vâng, lambda trong mẫu trên có thể được cải thiện một chút, nhưng đó chỉ là một chi tiết. Tuy nhiên, tôi không chắc mình có thể làm gì với shared_ptrs và con trỏ. Ý tưởng là triển khai các khối trình vòng lặp với các coroutines, chính xác cách chúng được triển khai trong C #, để cung cấp các đường dẫn dữ liệu và đánh giá lười biếng. Ví dụ: tại nguồn, chúng ta có thể có thứ gì đó "tạo ra" dữ liệu từ vùng chứa STL, nhưng sau đó chúng ta có một đường ống các thành phần phải hoạt động giống như IEnumerator, mang lại dữ liệu từ các quy trình đồng. Bạn sẽ nghĩ đến giao diện nào cho phiên bản C ++ của LINQ?
Paolo Severini

5
Phương pháp tiếp cận dựa trên mẫu biểu thức, tĩnh là điều tôi đã nghĩ đến. Đọc lên nó.
Xeo

Cảm ơn bạn Xeo thật! Các mẫu biểu thức rất thú vị, tôi chắc chắn sẽ cố gắng tìm hiểu thêm về chúng. Bạn có nghĩ rằng chúng có thể được sử dụng để triển khai đánh giá lười biếng theo nghĩa LINQ (với các chuỗi "mang lại" một mục tại một thời điểm?) Vì tôi nghĩ đây là ý chính của LINQ: bạn không muốn sửa đổi các vùng chứa hiện có, và bạn không muốn tạo cùng một lúc tất cả dữ liệu cho các vùng chứa tạm thời là đầu ra của tất cả các toán tử được nối trong một biểu thức LINQ. Chắc là lười, nếu không thì không cần phải bận tâm đến LINQ, bạn có thể làm mọi thứ với thuật toán stl, std và lambdas.
Paolo Severini

2
Chà .. chỉ cần áp dụng bất cứ điều gì bạn muốn chỉ trong quá trình tham chiếu của một trình lặp. Ngoài ra, hãy xem Boost.Range .
Xeo

3

Đây là một giải pháp thay thế khác chỉ đơn giản là một trình bao bọc xung quanh các thuật toán boost và stl, và do đó bạn nhận được hầu hết các lợi ích về hiệu suất của những triển khai đó.

Nó hoạt động như thế này:

std::vector<int> xs;
auto count = from(xs)
   .select([](int x){return x*x;})
   .where([](int x){return x > 16;})
   .count();
auto xs2 = from(xs)
   .select([](int x){return x*x;})
   .to<std::vector<int>>();

Lưu ý rằng một số phương pháp trả về proxy cho các phạm vi trống, ví dụ:

std::vector<int> xs;
auto max = from(xs)
   .select([](int x){return x*x;})
   .where([](int x){return x > 16;})
   .max()
   .value_or(default_max_value);

Phản hồi được hoan nghênh.


Làm rất tốt, tôi thích nó.
Tim Sylvester

3

Thực ra nếu bạn chỉ muốn sử dụng Linq để hiểu danh sách, bạn có thể sử dụng thư viện Linq này . Nó yêu cầu C ++ 11 (mặc dù nó sẽ hoạt động trong MSVC 2010) và Boost. Với thư viện, bạn có thể viết các truy vấn linq như thế này:

struct student_t
{
    std::string last_name;
    std::vector<int> scores;
};

std::vector<student_t> students = 
{
    {"Omelchenko", {97, 72, 81, 60}},
    {"O'Donnell", {75, 84, 91, 39}},
    {"Mortensen", {88, 94, 65, 85}},
    {"Garcia", {97, 89, 85, 82}},
    {"Beebe", {35, 72, 91, 70}} 
};

auto scores = LINQ(from(student, students) 
                   from(score, student.scores) 
                   where(score > 90) 
                   select(std::make_pair(student.last_name, score)));

for (auto x : scores)
{
    printf("%s score: %i\n", x.first.c_str(), x.second);
}

Cái nào sẽ xuất ra:

Omelchenko score: 97
O'Donnell score: 91
Mortensen score: 94
Garcia score: 97
Beebe score: 91

2

C ++ 0x, hoặc bất cứ thứ gì nó được gọi, có một từ khóa mới được gọi là từ khóa autocho phép suy luận kiểu. Và vâng, sẽ có lambda sắp ra mắt cho C ++. Ngoài ra, một tìm kiếm nhanh trên Google đã tiết lộ điều này, CLinq .


2

Đây là cách triển khai của tôi về c ++ - linq với c ++ 11 (bằng tiếng Trung Quốc):

http://www.cnblogs.com/cbscan/archive/2012/10/20/2732773.html

Nó hỗ trợ các tính năng như "truy vấn trì hoãn", "dựa trên ngăn xếp" (sử dụng toán tử mới càng ít càng tốt), "sao chép ngữ nghĩa" (vì vậy bạn có thể lặp lại một truy vấn nhiều lần sau khi sao lưu nó), v.v.

Nó cũng hỗ trợ hàng tá chức năng bao gồm "từ, chọn, ở đâu, truyền, phạm vi, tất cả, bất kỳ, truyền, trung bình, chứa, đếm, đầu tiên, cuối cùng, đầu, đuôi, nhómBy, takeUntil, bỏ qua, tối đa, tối thiểu, giảm, duy nhất, sắp xếp, ngẫu nhiên, giao nhau, _union ".

Tôi nghĩ rằng mã của tôi đủ đơn giản để hiểu và mở rộng cho bất kỳ ai.


-4

Tôi không nghĩ C ++ có đường trình biên dịch để xử lý những thứ như biểu thức lambda, vì vậy không, điều đó sẽ không xảy ra.


5
C ++ 0X có lambda, vì vậy về mặt lý thuyết là có thể thực hiện được, nhưng có, đây không phải là một nhiệm vụ dễ dàng.
Robert Gould

7
Thư viện Boost.Phoenix cũng thêm Lambdas vào C ++ mà không cần bất kỳ thủ thuật biên dịch trước nào. Xem tinyurl.com/d4y9se [boost.org] Tất nhiên, với C ++ 0x, việc này trở nên dễ dàng hơn! Một bài viết hay về cách thực hiện LINQ với c ++ 0x tinyurl.com/d9zlsc [blogspot.com]
jk.

3
LOL, với sự trợ giúp của boost :: lambda, một số thủ thuật mẫu và trong một số trường hợp nhất định, trình biên dịch trước tôi đã có thể đưa ra cú pháp sau: from(v).where(&_1 ->* &Person::age >= 18).order_by(Person, age).top(5).order_by(Person, name)để chọn năm người lớn trẻ nhất từ ​​std :: vector <Person> và trả lại chúng theo thứ tự bảng chữ cái. Vì vậy, tôi sẽ nói rằng C ++ là đủ cho công việc ...
Andreas Magnusson

1
@Andreas, ồ, tôi nghĩ rằng bạn đang sử dụng siêu năng lực của LINQ để chuyển đổi LINQ thành truy vấn SQL. Trong trường hợp đó, bạn cần AST và lấy nó bằng C #. Bạn không thể làm điều đó trong C ++ AFAIK.
Elazar Leibovich

1
@Elazar & @Andreas - thực sự có hai hương vị của LINQ. Một cái hoạt động như tôi tin là của Andreas, và cái kia sử dụng cây biểu thức (một tập hợp con của AST đầy đủ) có thể được diễn giải lại trong mã để tạo SQL hoặc một số biểu diễn truy vấn khác. Để biết thêm thông tin về biểu mẫu thứ hai, hãy tra cứu Expression<T>trong tài liệu C #.
Drew Noakes
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.