람다 (λ) 란 표현식에서는 c++11 에서? 한 때 사용합니까? 어떤 수준의 문제를 해결할 수 있는 t # 39, 그 전에 유용하던가요 wasn& 뚭컻?
및 활용 사례를 몇 가지 예를 약간만이라도 유용합니다.
'일반', '와' 표준용량 변형 std::for_each dm_ownerdm_owner c++컴파일러는 유용한 것 같은 기능을 사용할 수 있는 매우 유용합니다. 특히 상당히 번거로운 죄송합니다. 수도 있습니다 사용할 경우 [함자] (https://stackoverflow.com/questions/356950/c-functors-and-their-uses) 싶은 고유하므로 적용하십시오 해당 함수.
#include <algorithm>
#include <vector>
namespace {
struct f {
void operator()(int) {
// do something
}
};
}
void func(std::vector<int>& v) {
f f;
std::for_each(v.begin(), v.end(), f);
}
'F' 한 번 사용할 경우에만 쓸 수 있을 것 같다, 이런 사소한 일을 그냥 전체 배치하십시오 오버킬 특정 클래스 및 원-부트 끄기입니다.
나는 C++03 에서 쓸 수 있습니다 다음, 같은 일이 계속 함자 지역:
void func2(std::vector<int>& v) {
struct {
void operator()(int) {
// do something
}
} f;
std::for_each(v.begin(), v.end(), f);
}
그러나 이는 미허용, 'f' 템플리트를 기능을 C++03 전달될 수 없습니다.
C++11 은 람다 인라인, 함자 f '익명' 구조체입니다 재장착하려면 쓸 수 있습니다. 중소기업에 대한 간단한 예제를 읽을 수 있습니다 (그것은 계속 한 곳에서 모든 것을) 이 더 필요하고 간단해진다는 유지하기 위해, 예를 들어 가장 간단한 형태에서:
void func3(std::vector<int>& v) {
std::for_each(v.begin(), v.end(), [](int) { /* do something here*/ });
}
람다 함수에 대한 익명 함자 통사 설탕 불과합니다.
간단히 람다 (λ) 는 당신꺼에요 복귀하십시오 유형의 경우, 유추, 예:
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) { return d < 0.00001 ? 0 : d; }
);
}
그러나 쓰기 시작하면 금방 다시 만날 수 없는 경우가 있습니다 더 복잡한 람다 타입 유추 의해 컴파일러, 예:
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) {
if (d < 0.0001) {
return 0;
} else {
return d;
}
});
}
해결하십시오 람다 함수에 대한 유형을 사용하여 명시적으로 지정할 수 있습니다 '반환 ->. T '.
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) -> double {
if (d < 0.0001) {
return 0;
} else {
return d;
}
});
}
void func5(std::vector<double>& v, const double& epsilon) {
std::transform(v.begin(), v.end(), v.begin(),
[epsilon](double d) -> double {
if (d < epsilon) {
return 0;
} else {
return d;
}
});
}
참조 및 가치, 지정할 수 있는 '에서 모두 사용하여 캡처할 수 있습니다.' 와 '=' & 각각:
[&, 엡실론] '-' 참조별로 캡처하기
생성된 '연산자 ()' 가 '상수' 기본적으로 '상수' 액세스하면 기본적으로 그 의미 있는 포착하는 것입니다. 이 같은 결과를 얻을 수 있는 것 같은 효과가 전화를 통해 각 입력 마크 '는 람다 (λ) 로 변경 가능' 그러나 요청할 수 있는 '연산자 ()' 즉 '상수' 이 아니다.
<! - 할 일: 이 멤버 변수, 함수 포인터 전환 및 기본 인수만 캡처, 예외 - >.
C++ 에서 시작된 람다 함수 개념을 람다 및 함수형 프로그래밍. 람다 a 는 익명의 유용한 기능입니다 (아닌 실제 프로그래밍 이론) 을 파선-짧은 스니핏 재사용합니다 및 만한 것은 불가능한 않는비즈니스 코드 이름.
이렇게 정의된 함수를 람다 a 는 C++ 언어로
[]() { } // barebone lambda
또는 그 영광을
[]() mutable -> T { } // T is the return type, still lacking throw()
' []' 는 ',' () {} '와' 인수 목록이 캡처하기 나열하십시오 함수가 된다.
이 중 어떤 람다 함수 내에 캡처하기 eventtest 나열하십시오 외부에서 바디입니다, 어떻게 사용할 수 있어야 합니다. 될 수 있습니다.
위의 모든 쉼표로 구분된 목록 '에 함께 사용할 수 있어 [x, y, &]'.
다른 것과 같은 C++ 함수의 인수가 목록.
코드가 실행될 때 실제로 람다 (λ) 이라고 합니다.
람다 하나뿐인 경우 반환 유형 가운데에는 생략해야 수 있으며 복귀하십시오 데클티페 암시적입니다 유형 ' (return_statement)'.
만약 람다 (λ) 는 선택함 변경 가능 (예를 들어 ' [] () {}' 변경 가능) 이 값은 지금까지 의해 캡처됩니다 값을 변형 수 있습니다.
람다 에서 정의된 표준 라이브러리 (iso) 에서 사용 편의성 및 사용자 don& 등 여러 가지 의문이 많은 이점을 막대에서는 지금 할 수 있는 작은 단순화됩니다 t # 39, 그들의 코드를 일부 내시경이요 함자
C++14 는 다양한 제안을 있는 람다 확장되었습니다.
이제 함께 할 수 있는 요소로 초기화되어야 캡처하기 목록 '='. 따라서 이름바꾸기를 변수 및 캡처하려면 의해 움직인다. 예를 들어, 표준 가져온 것입니다.
int x = 4;
auto y = [&r = x, x = x+1]()->int {
r += 2;
return x+2;
}(); // Updates ::x to 6, and initializes y to 7.
방법이 나와 함께 ':' 표준용량 움직이십시오 캡처하려면 및 원-부트 출처 위키백과
auto ptr = std::make_unique<int>(10); // See below for std::make_unique
auto lambda = [ptr = std::move(ptr)] {return *ptr;};
이제 람다 ('자동' 와 'T' 이 될 경우 일반 'T' 등이 인수 어디선가 문자 템플리트를 주변 유효범위):
auto lambda = [](auto x, auto y) {return x + y;};
C++14 복귀하십시오 유형의 모든 기능을 사용할 수 있도록 제한할 기능 유추 ',' 형태의 복귀하십시오 표현식에서는 않습니다. 이 또한 람다 연장되었습니다.
일반적으로 람다 표현식은 캡슐화됨 알고리즘을 사용할 수 있도록 다른 함수에 전달할 수 있습니다. 그러나 정의마다 , 실행하십시오 람다 즉시 가능하다.
[&](){ ...your code... }(); // immediately executed lambda expression
기능적인 면에서 동등한
{ ...your code... } // simple code block
따라서 람다 표현식에서는 리팩토링 복잡한 기능을 강력한 도구입니다. 먼저 랩할 람다 함수 코드 섹션에 위와 같이. 중간 과정을 수행할 수 있는 테스트 명시성 매개변수화를 점차 각 단계 이후. 코드 블록 나면 완전히 패라메트릭화 (의해) 의 제거 '& 것처럼,') 이 정상적인 기능을 외부 위치로 저회가 코드만이 이동할 수 있습니다.
마찬가지로, 람다 표현식 com/go/4e6b330a_kr 초기화하지 결과를 바탕으로 한 알고리즘입니다 사용할 수 있습니다 .
int a = []( int b ){ int r=1; while (b>0) r*=b--; return r; }(5); // 5!
, 길을 따라 분햘 프로그램에 전달하는 것이 유용할 수 있는 논리를 fopen 람다 표현식 인수로 다른 람다 표현식입니다.
[&]( std::function<void()> algorithm ) // wrapper section
{
...your wrapper code...
algorithm();
...your wrapper code...
}
([&]() // algorithm section
{
...your algorithm code...
});
람다 표현식 이용하면 네스트된 기능ᆞ기술과 라는 만들 수 있는 편리한 방법으로 중복을 방지할 수 없다. 또한 람다 release. 사용하는 경향이 있는 박스트롤의 조금 더 눈을 제대로 기능할 때 아닌 사소한 매개변수입니다 반군지역 비교했을 때 익명 인라인 람다) 는 다른 함수. 참고: # 39, 이후 이 세미콜론 닫기와 굽은 brace. don& t forget
auto algorithm = [&]( double x, double m, double b ) -> double
{
return m*x+b;
};
int a=algorithm(1,2,3), b=algorithm(4,5,6);
이후 많은 경우, 함수에 대한 객체에는 초기화하지 오버헤드에 프로필링 통해 이를 재작성할 정상적인 기능을 선택할 수 있습니다.
Q: 람다 (λ) 란 표현식에서는 c++11 에서?
A: 후드 아래에 있는 것이 너무 const 연산자 () 의 객체에는 클래스를 자동으로 생성됩니다. 및 폐쇄 등 호출됨 객체에는 만든 컴파일러와의.
하지만 일반적으로 더 나은 코드 생성 람다. 클로저 허용하시겠습니까 통해 전체 인라이닝 호출한다.
Q: 한 때 사용합니까?
A: 단순하고 작은 logic" 정의하십시오 "; 이전 세대 실행하십시오 질문이예요 컴파일러와의 요청한다. You give a 컴파일러와의 있는 일부 표현식에서는 원하는걸까요 δ1 연산자 (). 다른 모든 물건을 컴파일러와의 낼 수 있을 수 있습니다.
Q: 어떤 수준의 문제를 해결할 수 있는 t # 39, 그 전에 유용하던가요 wasn& 뚭컻?
A: 이는 같은 연산자 오버로딩을 기능을 추가, 사용자 정의 구문 함정이거나 설탕 대신 불필요한 코드를 흐름선 랩 (wrap it 비용 절감 오페라티온s.부트 스베르타치 실제 클래스, 1-3 흐름선 일부 논리를 상술합니다.! 일부 엔지니어들은 생각하노라 다음 기회를 줄 수 있을 경우 그 크기가 작은 오류뿐만 항목이없습니다 (I& # 39 m, 역시 그렇게 생각합니다.)
auto x = [=](int arg1){printf("%i", arg1); };
void(*f)(int) = x;
f(1);
x(1);
1. 캡처되는 값. 어떤 캡처하려면 수 있습니다.
1.1. 스토리지 기간 (람다 정적 변수를 참조입니다 수 있습니다. 그들은 모두 캡처됩니다.
1.2. 람다 캡처용으로 value" " 값을 통해 사용할 수 있습니다;;). 이러한 경우 캡처되는 var 복사됩니다 함수 객체 (폐쇄).
[captureVar1,captureVar2](int arg1){}
1.3. 너회가 캡처하기 no. 참조입니다. &. - 이 컨텍스트로 아닌 짓궂군요 참조 포인터를 가진다.
[&captureVar1,&captureVar2](int arg1){}
1.4pb. 캡처하려면 표기법을 쓰고 있는 모든 값에 의해, 또는 참조별로 비정적 var
[=](int arg1){} // capture all not-static vars by value
[&](int arg1){} // capture all not-static vars by reference
1.5. 캡처하려면 표기법을 쓰고 있는 모든 값에 의해, 또는 참조별로 지정하고 떨어지게 비정적 var. 더. 예를 들면 다음과 같다: 하지만 모든 정적임 없습니다. 캡처하기 var 값으로 참조별로 캡처하기 param2
[=,&Param2](int arg1){}
하지만 모든 정적임 없습니다. 캡처하기 var 참조별로 param2 캡처하기 by value
[&,Param2](int arg1){}
2. 반환 유형 공제
2.1. 람다 (λ) 반환 유형 중 하나가 될 수 있으면 람다 유추 표현식입니다. 정보기술 (it) 또는 명시적으로 지정할 수 있습니다.
[=](int arg1)->trailing_return_type{return trailing_return_type();}
만약 람다 (λ) 는 둘 이상의 표현식에서는 관심용 반환 유형 통해 지정되어야 합니다 후행 반환 유형. 또한 자동 구문 및 멤버 함수를 비슷한 기능을 적용할 수 있습니다.
3. 캡처되는 값. 너희는너희가 캡처하기 수 없습니다.
3.1. 로컬 객체의 멤버 변수 var, 데이터만 캡처하기 않을 수 있습니다.
4. С런버시언스
4.1!! 익명의 함수를 람다 함수 포인터 표시되지 않고 있지 않지만, 암시적으로 변환할 수 덜 캡처하기 람다 함수 포인터.
람다 문법을 C++ 프로그래밍 언어를 위한 작업에 대한 자세한 정보를 얻으실 수 있습니다 구배면에 # 337, 16-01-2012, 5.1.2. 람다 표현식, p.88
C++14 디스크입니다. diskid " init 에 추가 기능을 가지는 capture"; 추가되었습니다. 이 데이터를 아르비타리리 진행하십시오 허용하시겠습니까 폐쇄 선언 (구성원:
자동 토프로이트 = []}, {반품하십시오 (int value) 부동 (가치). 자동 보간하기 = [분 = 토프로이트 (0), 개/최대 토프로이트 (255)] (정수 값), float -> 복귀하십시오 (값 - 분) / (max - 분),}, {
한 익명의 함수를 람다 함수는 만든 인-라인. 일부 업체는 이 캡처하기 변수로 설명했다. (예: http://www.stroustrup.com/C++11FAQ.html # 람다) 수축됐는데 몇 가지 제한이 있다. 예를 들어, 이 같은 콜백하는 인터페이스입니다 there& s # 39.
void apply(void (*f)(int)) {
f(10);
f(20);
f(30);
}
별색 바로 사용할 수 있는 함수를 작성할 수 있었던 것과 같은 적용하십시오 다음과 같습니다.
int col=0;
void output() {
apply([](int data) {
cout << data << ((++col % 10) ? ' ' : '\n');
});
}
void output(int n) {
int col=0;
apply([&col,n](int data) {
cout << data << ((++col % 10) ? ' ' : '\n');
});
}
c++11 의 한계 때문에 표준. 캡처, 사용하려면 라이브러리와 의존하고 있습니다.
#include <functional>
(또는 다른 STL 라이브러리 같은 알고리즘을 사용하여 간접적으로 이해했소) 한 후 정상적인 기능을 표준용량 함수 작동합니까 반군지역 대신 다음과 같은 매개 변수로
#include <functional>
void apply(std::function<void(int)> f) {
f(10);
f(20);
f(30);
}
void output(int width) {
int col;
apply([width,&col](int data) {
cout << data << ((++col % width) ? ' ' : '\n');
});
}
'설명' 이 (가) 에서 볼 때 가장 좋은 람다 (λ) 는 그의 저서 '의 저자 표현식에서는 c++컴파일러는 비야네 스트롭스트룹 C++ 프로그래밍 언어' 11 장 ([isbn 13: 978-0321563842] [1]).
>. 람다 표현식 a 람다, 때로는) 라고도 함 >. (엄밀히 말하면, 하지만 잘못 나타난다) 를 함수 또는 >. 익명 함수 정의 및 표기, 람다 (λ) 는 간편화된 사용하는 객체에는 . 대신, 나중에 연산자에서 () 라는 정의 클래스를 함께 해당 클래스의 객체를, 그리고 있다. >. 이를 호출하는 대표 사용할 수 있습니다.
>. 이 때 특히 유용합니다 표시됨과 작업을 전달하십시오 싶다. >. 인수 충족되었으며 알고리즘입니다. 그래픽 사용자 인터페이스 (gui) 환경에서 >. 이러한 작업은 종종 콜백 (및 다른) 로 불린다.
여기 내 생각 없이 해결할 수 있는 모든 조치를 수행됨 람다 표현식에서는 하였으나 훨씬 더 코드와 함께 훨씬 큰 문제는 복잡성입니다. 람다 이 방식으로 표현식에서는 최적화 및 사용자 코드에 대한 방법이 있어 더욱 매력적이다. 슬픈 스트라우스토프) 가 있다.
>. 최적화를 위한 효과적인 방법
람다 표현식에서는 통해
void print_modulo(const vector<int>& v, ostream& os, int m) // output v[i] to os if v[i]%m==0
{
for_each(begin(v),end(v),
[&os,m](int x) {
if (x%m==0) os << x << '\n';
});
}
통하여, 또는 함수
class Modulo_print {
ostream& os; // members to hold the capture list int m;
public:
Modulo_print(ostream& s, int mm) :os(s), m(mm) {}
void operator()(int x) const
{
if (x%m==0) os << x << '\n';
}
};
심지어
void print_modulo(const vector<int>& v, ostream& os, int m)
// output v[i] to os if v[i]%m==0
{
class Modulo_print {
ostream& os; // members to hold the capture list
int m;
public:
Modulo_print (ostream& s, int mm) :os(s), m(mm) {}
void operator()(int x) const
{
if (x%m==0) os << x << '\n';
}
};
for_each(begin(v),end(v),Modulo_print{os,m});
}
할 수 있는 '이름' 람다 표현식은 다음과 같은 경우 u u
void print_modulo(const vector<int>& v, ostream& os, int m)
// output v[i] to os if v[i]%m==0
{
auto Modulo_print = [&os,m] (int x) { if (x%m==0) os << x << '\n'; };
for_each(begin(v),end(v),Modulo_print);
}
또 다른 간단한 샘플링합니다 또는 solaris.
void TestFunctions::simpleLambda() {
bool sensitive = true;
std::vector<int> v = std::vector<int>({1,33,3,4,5,6,7});
sort(v.begin(),v.end(),
[sensitive](int x, int y) {
printf("\n%i\n", x < y);
return sensitive ? x < y : abs(x) < abs(y);
});
printf("sorted");
for_each(v.begin(), v.end(),
[](int x) {
printf("x - %i;", x);
}
);
}
다음 생성됩니다.
>. 0 >. >. 1 >. >. 0 >. >. 1 >. >. 0 >. >. 1 >. >. 0 >. >. 1 >. >. 0 >. >. 1 >. >. 3 - 0 - 1, x, x, x 조르테데스, x, x, x 4 - 5 - 6 ~ 7 - 33.
[] '는': '-' 이 캡처하기 목록이거나 도입기 람다 람다 액세스하려면 경우 해당 지역 환경 '없이' 우리가 쓸 수 있다.
Quote from book:
>. 람다 표현식 a 의 첫 번째 문자는 항상 [. 람다 a >. 도입기 다양한 형태를 취할 수 있다. >. >. [] •: 빈 캡처하기 목록. 이 >. 주변 지역 이름을 알 수 없는 컨텍스트로 에서 사용할 수 있습니다. >. 람다 (λ) 의 바디입니다. 이러한 데이터는 람다 표현식에서는 얻은 >. 인수만 호출하든 비지역 com/go/4e6b330a_kr. >. [&] • >,: 의해 간접적으로 캡처하기 >. 참조입니다. 모든 지역 이름을 사용할 수 있습니다. 모든 지역 변수는 >. 액세스하는지 참조입니다. >. >. [=] •: 암시적으로 캡처하기 by value. 모든 로컬 >. 이름을 사용할 수 있습니다. 모든 지역 변수를 복제본입니다 이름) 은 다음과 같은 뜻이 있다. >. 이 시점에서 조롱했기 호출하십시오 람다 표현식입니다. >. >. • [캡처하기 목록] 명시성 캡처하기. 이 지역 변수를 스크램블된 캡처하기 목록 는 명단과 캡처되면 (즉, 저장됩니까 객체에는) 참조별로 또는 by value. 변수 이름을 가진 & 옵니다. 의해 캡처되지 >. 참조입니다. 다른 변수의 값에 의한 캡처되지. 캡처할 수 목록 >. 이 이름 뒤에 내용이 들어 있다. 요소로. >. [&, 캡처하기 목록] • >,: 로 놓여 있는 것은 모든 로컬 변수 이름을 가진 사람은 참조별로 캡처하기 암시적으로 명단요 이 목록은 해당 캡처하기 포함할 수 있습니다. 나열되는지 &, 이름 앞에는 수 없습니다. 변수 이름을 올렸다 >. 캡처하기 목록.직렬 캡처되지 by value. >. [= 캡처하기 목록] •*: 모든 로컬 변수 값을 기준으로 캡처하기 암시적으로 이름이 언급되지 않은 명단요 이 목록은 해당 캡처하기 포함할 수 없습니다. 이름이 나열된 선행되어야 &. 청정도 바리 참조별로 캡처되지 캡처하기 목록에 이름을 올렸다.
>. 단, 현지 이름 앞에는 &. 항상 의해 캡처됩니다 >. 참조입니다 및 현지 이름 없는 의해 사전 다시 &. 항상 의해 캡처됩니다 >. 값. 참조별로 캡처하기 변수를 수정할 수 만 >. 호출 환경.
'형식' 람다 표현식
추가 참조:
[1]: https://www.amazon.com/c-programming-language-4th/dp/ 0321563840
[3]: https://en.wikipedia.org/wiki/Anonymous_function # C. 2B.2B_.28since_C.2B.2B11.29
void process_z_vec(vector<int>& vec)
{
auto print_2d = [](const vector<int>& board, int bsize)
{
for(int i = 0; i<bsize; i++)
{
for(int j=0; j<bsize; j++)
{
cout << board[bsize*i+j] << " ";
}
cout << "\n";
}
};
// Do sth with the vec.
print_2d(vec,x_size);
// Do sth else with the vec.
print_2d(vec,y_size);
//...
}
람다 없이 위해 무언가 할 수 있습니다 '다른' bsize 건으로 집계됐다. 물론 만들 수 있습니다 싶은 범위 내에서 사용 용도를 제한하는 기능을 하지만 와일드링이 영혼의 사용자 함수? 이 요구 사항을 해당 사건의 본질을 충족합니다 람다 쉐퍼드도 사용한다.
yes, it on the go) 는 말 그대로 정의할 수 있습니다. 사용한다. 또 상위 함수은 유효범위 완료될 람다 함수 우리 곁을 떠났다.
11 개) 와 it like it 에 소개된 c++컴파일러는 c++컴파일러는 수명주기의 모든 가능한 배치하십시오 모두라뇨 사용하기 시작했다. 람다 예를 찾을 수 있으며 어떻게 여기 https://en.cppreference.com/w/cpp/language/lambda
람다 (λ) 는 제작되지 않은 도처에 있으며 모든 기능을 사용할 수 있는 람다 대체할 수 없습니다. # 39 의 가장 빠른 정상적인 기능을 it& 비교할 수도 없습니다. 가지고 있기 때문에 일부 오버헤드에 처리됩니까 할 의해 람다 (λ).
곧 이 도움을 줄 수 있는 경우도 있습니다. 기본적으로 코드 부분을 사용할 수 있으며, 이는 동일한 기능을 전화를 받고 있는 하나 이상의 고객이시간과 필요하지 않은 코드를 작성할 수 있도록 다른 곳에 독립형 함수은 일이다.
다음은 람다 (λ) 의 정의, 어떤 경우는 배경.
int main()
{
// Lambda & auto
int member=10;
auto endGame = [=](int a, int b){ return a+b+member;};
endGame(4,5);
return 0;
}
int main()
{
int member = 10;
class __lambda_6_18
{
int member;
public:
inline /*constexpr */ int operator()(int a, int b) const
{
return a + b + member;
}
public: __lambda_6_18(int _member)
: member{_member}
{}
};
__lambda_6_18 endGame = __lambda_6_18{member};
endGame.operator()(4, 5);
return 0;
}
그래서 어떤 종류의 오버헤드에 자도으로 알 수 있듯이, 이 때 사용한다. 그래서 그 모든 것은 이를 이용하는 것이 좋습니다. 이들은 해당 위치에 사용할 수 있습니다.
한 가지 문제는 문제를 해결합니다. https://stackoverflow.com/questions/31078201/code-simpler-than-lambda-for-a-call-in-constructor-that-uses-an-output-parameter
Const 멤버 함수 호출을 통해 해당 클래스의 초기화하지 수 있습니다, 그 값을 설정하는 등 출력입니다 뒤로를 제공하여 표시됨과 출력입니다 매개변수입니다.