2016-11-28 11 views
0

괄호로 펑키 한 비즈니스없이 C++에서 일회용 변수를 만들 수 있습니까?C++에 이동 및 삭제 의미가 있습니까?

const float phi = 0; 
{ 
    const float _phiTemp = atan2(tan(cluster.beta), tan(cluster.alpha)); 
    float& phiRef = const_cast<float&> phi; 
    phiRef = HALF_PI - std::abs(HALF_PI - std::abs(std::move(_phiTemp))); 
} 
// _phiTemp is disposed and phi is a const, and safely used in the calculation 
// through std::move() 

나는 실종 뭔가 : 여기

const float _phiTemp = atan2(tan(cluster.beta), tan(cluster.alpha)); 
const float phi  = HALF_PI - std::abs(HALF_PI - std::abs(_phiTemp)); 
// After running this code I want _phiTemp to be unaccessible, and the 
// compiler to send an error if I ever try 

내가 원하는 무엇의 긴 추한 구현 : 여기에

내가 무엇을 달성하고자하는의 예입니다? C++에서 "즉시"변수 처리가 있습니까?

+1

"C++에는"즉시 "변수 처리가 없습니까? *"예, 이미 그 예를 만들었습니다. 괄호를 사용하여 범위를 나타내며 범위는 수명을 나타냅니다. 그것에 대해 아무것도 못 생겼어. –

+0

글쎄, 순식간에 "현재 범위의 스택에서 변수를 제거하십시오."(+ 컴파일러가 변수가 더 이상 없다는 것을 알 수 있도록). –

+2

'phi'에서 const를 버리고 할당하면 동작이 정의되지 않습니다. – molbdnilo

답변

6

길고 추악한 구현은 정의되지 않은 동작이기도합니다. phiRef에 대한 쓰기는 const로 정의 된 변수에 대한 쓰기입니다.

당신이 할 수있는 최선 phi을 계산하는 함수를 작성하는 것입니다 -이 인라인을 수행하려는 경우, 당신은 람다를 작성할 수

const float phi = [&cluster]{ 
    const float phiTemp = atan2(tan(cluster.beta), tan(cluster.alpha)); 
    return HALF_PI - std::abs(HALF_PI - std::abs(phiTemp)); 
}(); 

을 ...하지만 여전히 매우 추한. 나는 C++이이 기능을 제공한다고 생각하지 않는다.

+1

저는 IIFE 람다가 짧은 코드를위한 최고의 C++ 11 솔루션이라고 생각합니다. (이것은 실제 코드에서 사용하는 것입니다). pre-C++ 11 및 더 긴 코드의 경우 별도의 명명 된 함수를 사용하십시오. – KABoissonneault

0

Martin Bonner이 올바른 경로에 있습니다. lambda는 사용자가 원하는대로 도우미 변수를 선언 할 수있는 "scope-with-return"으로 잘 작동합니다. 아래는 내가 한 단계 더 가져가 내 개인 툴킷에서 만든 것입니다 :

const float phi = glk_initBlock { 
    const float phiTemp = atan2(tan(cluster.beta), tan(cluster.alpha)); 
    return HALF_PI - std::abs(HALF_PI - std::abs(phiTemp)); 
}; 
+1

Eep! 그래서 당신은 람다를 magic'operator *'(그것을 호출하고 결과를 반환)에 전달하여 호출합니다. 블록 뒤에'()'이 필요 없다는 것이 포인트입니다. 저것은 저를 아주 영리하게 때린다 ... 그러나 나가 너무 똑똑한 또는 아닙니다인지 나는 확실하지 않다. –

+0

... 내 대답에 구문 수정을 주셔서 감사합니다! –

+0

@MartinBonner 나는이 속임수에 대해 아무런 신뢰를하지 않는다. 나는 그의 'ScopeGuard'에 관한 Andrei Alexandrescu의 이야기에서 그것을 배웠다. 그러나 나는 그것을 좋아한다 :) – Quentin

-1

내가 당신이 원하는 것은 임시 변수라고 생각합니다 :

namespace initBlock_detail { 
    struct tag { }; 

    template <class F> 
    decltype(auto) operator * (tag, F &&f) { 
     return std::forward<F>(f)(); 
    } 
} 

#define glk_initBlock \ 
    glk::initBlock_detail::tag{} * [&]() -> decltype(auto) 

호출 구문처럼 보인다. 중간 값을 지정하지 마십시오.

const float phi = HALF_PI - std::abs(
    HALF_PI - std::abs(
     atan2(
      tan(cluster.beta) 
      , tan(cluster.alpha) 
     ) 
    ) 
); 
+1

그것은이 예제에서 작동한다. 두 번째 표현식이 'const float phi = 2 * square (_phiTemp) + _phiTemp - 1;'(예 : –

+0

) 인 경우 작동하지 않습니다. 두 가지 이유로 실패합니다 : 1. 계산을 분리하는 목적을 상실합니다. 2. 예를 들어 같은 변수를 처음부터 계산하지 않고 재사용 할 수 없습니다. a * f (a)는 a를 두 번 계산해야한다는 것을 의미합니다. –

+0

가독성 주장은 주관적입니다. 한 번만 사용되는 임시 중간 변수에 대해서는 특별히 읽을 수있는 것이 없습니다. 나는 당신이 필요로하는 변수만을 선언하는 것이 더 명확하다고 생각한다. 두 번째 경우에는 값을 두 번 필요로한다. – caps