cpp.react 라이브러리의 C ++ 소스 코드에서 이상한 "-> * []"표현식
다음은 cpp.react 라이브러리 문서에서 찾은 C ++ 스 니펫입니다 .
auto in = D::MakeVar(0);
auto op1 = in ->* [] (int in)
{
int result = in /* Costly operation #1 */;
return result;
};
나는 ->* []표기법을 본 적이 없습니다 . 먼저 오타 일 뿐이라고 생각했지만 소스 코드 에서도 다음과 같은 표현을 찾았습니다 .
auto volume = (width,height,depth) ->* [] (int w, int h, int d) {
return w * h * d;
};
유효한 C ++ 11 (또는 C ++ 14)입니까? 무슨 뜻이에요?
링크 된 페이지의 유일한 예는 다음과 ->*같습니다.
auto in = D::MakeVar(0);
auto op1 = in ->* [] (int in)
{
int result = in /* Costly operation #1 */;
return result;
};
auto op2 = in ->* [] (int in)
{
int result = in /* Costly operation #2 */;
return result;
};
여기에 내 추측이있다. 어떤 타입이 멤버에D::MakeVar() 대한 포인터 를 오버로드하면 어떤 타입이 반환되고 ->*그 오버로드 된 연산자에 대한 두 번째 인자는 함수 객체, 즉 람다 표현식이다.
이 예는 다음과 같습니다.
auto volume = (width,height,depth) ->* [] (int w, int h, int d) {
return w * h * d;
};
나는 어떤 유형 width, height& depth가 쉼표 연산자를 오버로드하는지 추측 하고 있으며 결과는 산출하는 것과 동일한 유형 MakeVar또는 오버로드하는 다른 유형을 산출 ->*합니다. 나머지는 첫 번째 예와 동일합니다.
@Praetorian의 대답 이 맞습니다. 이것은 cpp.react의 코드입니다.
///////////////////////////////////////////////////////////////////////////////////////////////////
/// operator->* overload to connect inputs to a function and return the resulting node.
///////////////////////////////////////////////////////////////////////////////////////////////////
// Single input
template
<
typename D,
typename F,
template <typename D_, typename V_> class TSignal,
typename TValue,
class = std::enable_if<
IsSignal<TSignal<D,TValue>>::value>::type
>
auto operator->*(const TSignal<D,TValue>& inputNode, F&& func)
-> Signal<D, typename std::result_of<F(TValue)>::type>
{
return D::MakeSignal(std::forward<F>(func), inputNode);
}
// Multiple inputs
template
<
typename D,
typename F,
typename ... TSignals
>
auto operator->*(const InputPack<D,TSignals ...>& inputPack, F&& func)
-> Signal<D, typename std::result_of<F(TSignals ...)>::type>
{
return apply(
REACT_IMPL::ApplyHelper<D, F&&, TSignals ...>::MakeSignal,
std::tuple_cat(std::forward_as_tuple(std::forward<F>(func)), inputPack.Data));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/// Comma operator overload to create input pack from 2 signals.
///////////////////////////////////////////////////////////////////////////////////////////////////
template
<
typename D,
typename TLeftVal,
typename TRightVal
>
auto operator,(const Signal<D,TLeftVal>& a, const Signal<D,TRightVal>& b)
-> InputPack<D,TLeftVal, TRightVal>
{
return InputPack<D, TLeftVal, TRightVal>(a, b);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/// Comma operator overload to append node to existing input pack.
///////////////////////////////////////////////////////////////////////////////////////////////////
template
<
typename D,
typename ... TCurValues,
typename TAppendValue
>
auto operator,(const InputPack<D, TCurValues ...>& cur, const Signal<D,TAppendValue>& append)
-> InputPack<D,TCurValues ... , TAppendValue>
{
return InputPack<D, TCurValues ... , TAppendValue>(cur, append);
}
보시 다시피 operator->*신호 ( D::MakeVar(0))와 펑터 (람다)를 받는 오버로드 된 자유 함수
operator,두 개의 신호를받는 자유 기능
(저자 여기)
우선 Praetorians의 대답은 정확하지만 조금 더 자세히 설명하고 싶습니다.
Note that this library is still very experimental and I'm still working on the documentation. The current state of said documentation can be found in the wiki, in particular https://github.com/schlangster/cpp.react/wiki/User-Guide-%7C-Signals is related to the question.
Here's a more verbose example:
int calcVolume(int w, int h, int d) { return w*h*d; }
D::VarSignalT<int> width = D::MakeVar(1);
D::VarSignalT<int> height = D::MakeVar(2);
D::VarSignalT<int> depth = D::MakeVar(3);
D::SignalT<int> volume = MakeSignal(&calcVolume, width, height, depth);
Observe(volume, [] (int v) {
printf("volume changed to %d\n", v);
});
width.Set(10); // => volume changed to 60.
printf("volume: %d\n", volume.Value()); // short: volume()
It's sort of a bind (bind signals as function input), but it's NOT the same as a reverse std::bind. volume is not a function object. In particular, volume is not recalculated when you call Value(), it is recalculated when one of its dependent signals changes, the result is saved, and Value() returns it. So it's essentially push based change propagation with some extra features (no redundant updates, no glitches, optional implicit parallelization).
The problem is that MakeSignal gets confusing when mixed with temporary signals and lambdas:
// First create a temporary area signal, then use it as an argument for the volume signal
D::SignalT<int> volume = MakeSignal(
[] (int a, int d) { return a * d; },
MakeSignal(
[] (int w, int h) { return w * h; },
width, height),
depth);
Nobody wants to read stuff like that, right? At least I don't want to.
So there's an alternative syntax that moves the dependencies to the left, wrapped by SignalList.
// Note: Not sure if I have already pushed this variant yet
D::SignalT<int> volume =
MakeSignalList(
MakeSignalList(width, height).Bind([] (int w, int h) { return w * h; }),
depth
).Bind([] (int a, int d) { return a * d; });
And, finally, with the evil comma and ->* overloads:
D::SignalT<int> volume =
(
(width, height) ->* [] (int w, int h) { return w * h; },
depth
)
->* [] (int area, int d) { return a * d; };
The problem with this, as others have noted, is that anyone seeing it for the first time doesn't know what the heck is going on.
On the other hand, connecting signals to functions should be a very common task when using this library. Once you know what it does, the ->* version is more concise and it visualizes the dataflow graph (edges from width and height to the temporary area, edges from area and depth to volume).
ReferenceURL : https://stackoverflow.com/questions/23619152/strange-expression-in-c-source-code-of-cpp-react-library
'Program Club' 카테고리의 다른 글
| 1024 미만의 포트에 권한이 부여되는 이유는 무엇입니까? (0) | 2021.01.08 |
|---|---|
| 플라스크에서 g.user global을 사용하는 방법 (0) | 2021.01.08 |
| Dagger 2 예제 (0) | 2021.01.08 |
| 호스팅 된 CouchDB 서비스 제공자가 있습니까? (0) | 2021.01.08 |
| Jython을 사용하여 Python 스크립트를 JAR 파일로 배포합니까? (0) | 2021.01.08 |