C ++中列表理解的LINQ為C ++提供了LINQ的實現。當前,它僅支持C ++範圍,但確實支持LINQ的擴展和查詢方法。這是一個例子:
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 ++代碼將輸出此(是的是上面的C ++代碼):
Omelchenko score: 97
O'Donnell score: 91
Mortensen score: 94
Garcia score: 97
Beebe score: 91
使用|實現擴展。管道操作員。這使它們可以應用於任何範圍,而無需介入某些特殊的基礎類別。因此擴展可以這樣工作:
vector< int > numbers = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 };
auto r = numbers
| linq::where([]( int x) { return x > 2 ; })
| linq::select([]( int x) { return x * x; });支持的擴展方法是:
該庫還提供了一個range_extension類,也可以用來編寫您自己的擴展名。首先,將函數定義為函數對像類,例如:
struct contains_t
{
template < class Range , class T >
bool operator ()(Range && r, T && x) const
{ return (r | linq::find (x)) != boost::end (r); };
};然後使用靜態初始化初始化擴展名:
range_extension< contains_t > contains = {};然後可以像這樣使用擴展名:
if (numbers | contains( 5 )) printf( " We have a 5 " );所有LINQ查詢都必須從from開始。這指定了要用於lambdas的變量名稱以及將應用查詢的容器。另外,可以使用from語句的多個。
struct student
{
std :: string name ;
std :: vector < int > grades ;
student ( ) { }
template < class Range >
student ( std :: string name , Range && r )
: name ( name ) , grades ( boost :: begin ( r ) , boost :: end ( r ) )
{ }
} ;
std :: vector < student > students =
{
student ( "Bob" , { 90 , 100 , 75 } )
student ( "Tom" , { 92 , 81 , 70 } )
student ( "Terry" , { 105 , 98 , 94 } )
} ;
// { 90, 100, 75, 92, 81, 70, 105, 98, 94 }
auto q = LINQ ( from ( s , students ) from ( g , s . grades ) select ( g ) ) ;Where子句返回與謂詞匹配的元素。它是可選的,但必須在a from之後出現,如果有的話,應在select子句之前。
vector < int > v = { 1 , 3 , 4 , 5 } ;
// { 1, 3, 5 }
auto q = LINQ ( from ( i , v ) where ( i % 2 ) ) ;選擇子句將轉換應用於元素。它也是可選的,但應該是最後一個子句。
std :: vector < int > v = { 1 , 2 , 4 } ;
// { 3, 6, 24 }
auto q = LINQ ( from ( x , v ) select ( x * 3 ) ) ;orderby子句允許您指定元素以訂購範圍。此外,還可以在選擇器之前ascending或descending以指定訂購方向。默認值正在上升。
struct person
{
std :: string name ;
int age ;
person ( ) { }
person ( std :: string name , int age )
: name ( name ) , age ( age )
{ }
} ;
std :: vector < person > people =
{
person ( "Tom" , 25 ) ,
person ( "Bob" , 22 ) ,
person ( "Terry" , 37 ) ,
person ( "Jerry" , 22 )
}
// { "Jerry", "Bob", "Tom", "Terry" }
auto q = LINQ ( from ( p , people ) orderby ( p . age , descending p . name ) select ( p . name ) ) ;group子句將序列的元素分組。第一個參數是鍵選擇器,第二個參數是值選擇器。
struct person
{
std :: string name ;
int age ;
person ( ) { }
person ( std :: string name , int age )
: name ( name ) , age ( age )
{ }
} ;
std :: vector < person > people =
{
person ( "Tom" , 25 ) ,
person ( "Bob" , 22 ) ,
person ( "Terry" , 37 ) ,
person ( "Jerry" , 22 )
}
auto q = LINQ ( from ( p , people ) group ( p . age , p . name ) ) ; LINQ可以輕鬆地使用CGET:
cget install pfultz2/Linq
這將自動安裝增強依賴性。該庫也可以使用CMAKE手動安裝。
find_package(Linq)也可以從Cmake消費LINQ:
find_package(Linq)
target_linkq_libraries(yourLib linq::linq)
為了獲得全部支持,它需要叮噹聲或GCC,並提升。有部分支持視覺工作室。 Visual Studio不支持default_if_empty , group_by , group_join , join , order_by , select_many和then_by擴展,並且不支持從條款中orderby , group和嵌套。也許某些視覺工作室嚮導可以幫助找到MSVC錯誤的解決方法。
使用嵌套的lambdas實現了from語句的多個。但是,由於MSVC 2010中的錯誤,Nested Lambas不起作用(這應該在MSVC 2012中修復,但我尚未對其進行測試)。如果有一種方法可以在C ++中實現透明標識符,則可以避免嵌套的lambdas。
另外, let和join條款尚不支持。如果沒有Polymorhpic Lambdas的幫助,就無法支持into條款。
BSL-1.0