내가 필요한 기능이 있다고 가정 해 봅시다 std::function
.
void callFunction(std::function<void()> x)
{
x();
}
x
대신 const-reference를 전달해야합니까 ? :
void callFunction(const std::function<void()>& x)
{
x();
}
이 질문에 대한 답변은 기능에 따라 어떻게 달라 집니까? 예를 들어 클래스 멤버 함수 또는 생성자를 std::function
멤버 변수에 저장하거나 초기화하는 경우입니다.
답변
성능을 원하면 저장하는 경우 값을 기준으로 전달하십시오.
“UI 스레드에서 실행”이라는 기능이 있다고 가정하십시오.
std::future<void> run_in_ui_thread( std::function<void()> )
“ui”스레드에서 일부 코드를 실행 한 다음 future
완료되면 신호를 보냅니다 . (UI 스레드가 UI 요소를 엉망으로 만드는 UI 프레임 워크에서 유용합니다)
고려중인 두 가지 서명이 있습니다.
std::future<void> run_in_ui_thread( std::function<void()> ) // (A)
std::future<void> run_in_ui_thread( std::function<void()> const& ) // (B)
이제 다음과 같이 사용할 것입니다.
run_in_ui_thread( [=]{
// code goes here
} ).wait();
익명 클로저 (람다)를 생성하고 std::function
그것을 닫고, run_in_ui_thread
함수에 전달한 다음 메인 스레드에서 실행이 끝날 때까지 기다립니다.
(A)의 경우, std::function
는 람다에서 직접 생성 된 다음 run_in_ui_thread
. 람다는move
들어가므로 std::function
, 어떤 이동 가능한 상태라도 효율적으로 들어간다.
두 번째 경우, 임시 std::function
가 생성되고 람다는 move
그 다음에 임시로 생성됩니다.std::function
는에서 참조로 사용됩니다 run_in_ui_thread
.
지금까지는 두 가지가 동일하게 수행됩니다. 를 제외하고 run_in_ui_thread
함수 인수의 사본을 작성하여 ui 스레드로 보내 실행하십시오! (완료되기 전에 반환되므로 참조를 사용할 수는 없습니다). 사례 (A)의 경우, 우리는 단순히move
std::function
장기 저장에. (B)의 경우을 복사해야합니다 std::function
.
그 가게는 가치를 더 잘 전달합니다. 의 사본을 저장할 가능성이 있으면 std::function
값으로 전달하십시오. 그렇지 않으면, 어느 쪽의 방법은 대략 동등합니다 : 값을 기준으로 한 유일한 단점은 같은 부피가 큰 경우입니다std::function
를 가지고 다른 하위 메소드를 사용한 후에 하나의 하위 메소드를 갖는 경우입니다. 그것을 막는 것은 a move
만큼 효율적 const&
입니다.
이제 둘 사이에 다른 상태가 있습니다. std::function
있습니다.
std::function
상점이 일부 객체를 저장 한다고 가정하십시오 .operator() const
하지만 는mutable
수정하는 데이터 멤버 (무례합니다!).
이 std::function<> const&
경우mutable
수정 된 데이터 멤버는 함수 호출에서 전파됩니다. 이 std::function<>
경우에는 그렇지 않습니다.
이것은 비교적 이상한 코너 사례입니다.
std::function
무게가 가볍고 저렴하게 움직일 수있는 다른 유형과 같이 취급하려고 합니다. 이동이 저렴하고 복사 비용이 많이들 수 있습니다.
답변
성능이 걱정되고 가상 멤버 함수를 정의하지 않은 경우에는 사용하지 않아야합니다. std::function
에는 전혀 합니다.
functor 유형을 템플릿 매개 변수로 만들면 std::function
functor 로직 인라이닝을 포함하여 보다 큰 최적화가 가능 합니다. 이러한 최적화의 효과는 전달 방법에 대한 copy-vs-indirection 문제보다 훨씬 클 것 std::function
입니다.
더 빠름 :
template<typename Functor>
void callFunction(Functor&& x)
{
x();
}
답변
C ++ 11에서와 마찬가지로 value / reference / const-reference로 전달하는 것은 인수로 수행하는 작업에 따라 다릅니다. std::function
다르지 않습니다.
값으로 전달 하면 인수를 변수 (일반적으로 클래스의 멤버 변수)로 이동할 수 있습니다.
struct Foo {
Foo(Object o) : m_o(std::move(o)) {}
Object m_o;
};
함수가 인수를 옮길 것임을 알면 이것이 최선의 해결책입니다.이 방법으로 사용자는 함수 호출 방법을 제어 할 수 있습니다.
Foo f1{Object()}; // move the temporary, followed by a move in the constructor
Foo f2{some_object}; // copy the object, followed by a move in the constructor
Foo f3{std::move(some_object)}; // move the object, followed by a move in the constructor
나는 당신이 이미 (비) const-references의 의미를 알고 있다고 생각하므로 요점을 다루지 않을 것입니다. 이것에 대해 더 많은 설명을 추가 해야하는 경우 물어보십시오. 업데이트합니다.