2013-04-26 3 views
3

내가 질문을 변경 한 이래서 이것은 my previous post의 말씨입니다. (아마도 새로운 질문으로 표시되지 않고 놓친 것 같습니다.) 나는 그것을 잘게 잘랐다. 배열은 조건부 연산자와 어떻게 작동합니까?

나는 기능을 좋아했다 : remove_some_extentsstd::remove_extent 메타 기능 지정된 횟수를 호출처럼 사용자 정의 클래스 템플릿입니다

#include <cstddef> 
#include <type_traits> 

template < typename E, typename T > 
inline constexpr 
auto checked_slice(E &&, T &&t) noexcept -> T && 
{ return static_cast<T &&>(t); } 

template < typename E, typename T, std::size_t N, typename U, typename ...V > 
inline constexpr 
auto checked_slice(E &&e, T (&t)[N], U &&u, V &&...v) 
-> typename remove_some_extents<T, sizeof...(V)>::type & 
{ 
    typedef typename std::remove_reference<U>::type     u_type; 
    typedef typename std::common_type<u_type, std::size_t>::type cmp_type; 

    return (u < u_type{}) || (static_cast<cmp_type>(u) >= 
    static_cast<cmp_type>(N)) ? throw e : checked_slice(static_cast<E &&>(e), 
    t[static_cast<U &&>(u)], static_cast<V &&>(v)...); 
} 

. "유형 Whatever(*)[Y]의 표현에서 유형 Whatever(&)[X][Y]의 참조의 잘못된 초기화"(또는 Whatever*에서 Whatever(&)[Z]) : 나는이 프로그램을 실행했을 때

, 나는 같은 오류의 무리를 얻었다. 내 해결 방법은 조건 식을 if - else 쌍으로 변환 한 다음 constexpr을 제거하는 것입니다.

나는 무엇이 잘못되었는지 알아 내려고 노력하고 있으므로 C++ (2011) 표준의 조건부 연산자에 대한 섹션을 살펴 보겠습니다. 그건 5.16 절입니다. 두 가지 가능한 동작 중 하나가 throw 명령이거나 그렇지 않으면 void 표현식 인 경우 조건부는 다른 표현식 유형을 갖지만 배열 대 포인터를 포함한 표준 변환이 다른 표현식에 적용됩니다. (2 단락에 나와 있습니다.) 그게 나를 망쳐 놓는 것 같아. 그 주위에 어떤 방법이 있습니까? 나는 배열 참조를 반환하는 것이 a-to-p 변환을 억제한다고 생각했다. if/else으로 만들면 왜 작동합니까?

답변

4

귀하의 분석은 정확합니다. 나는 두 개의 피연산자가 유형이 다르면 어떻게 될지를 모방하기 위해 비 -피연산자가 '부식'(즉, 일반적인 변환이 수행 됨)되는 것으로 의심합니다. 후자의 경우보다 더 자주 발생합니다 전체 조건 표현은 prvalue입니다.

것은

우리가 반드시 값 카테고리와 두 피연산자가 정확히 일치하는이 때, 우리가 사용할 수있는 조건식의 유형 모두에 대해 알고있는 한 상황은 우리의 장점 :

cond ? (throw e, t) : t 

는 좌변 될 것입니다 배열 참조 형의 if/else을 사용하는 경우

당신 때문에 언어가 수행하는 명령문으로 그러한 장애물을 발생하지 않았다 - (당신이 잘 당신의 재귀 호출을 연결할 수 있습니다 물론 마지막 피연산자는 그대로 t 일 필요는 없습니다.) 공통 유형 및 값 카테고리를 지정할 필요가 없습니다.

+0

컴파일러 웹 페이지에서 테스트 할 때 괄호가 필요하지 않습니다! '? :'에 대한 문법은'LOGICAL_OR_EXPR? EXPR : ASSIGN_EXPR'. 세 번째 섹션은 쉼표 연산자를 제외한 모든 것일 수 있습니다. 두 번째 섹션은 그 제한이 없습니다 * 없습니다 *! (첫번째 섹션은'? :'보다 높은 우선 순위를 가진 것입니다.) – CTMacUser

+0

괄호는 컴파일러의 이익을위한 경우는 거의 없습니다. –

+0

답변이 효과적이었습니다. 커밋 SHA 66ca088332dd1e57fdaf9e90749105224c301afb, 줄 136에서 159까지 [코드] (https://github.com/CTMacUser/ArrayMD/blob/master/include/boost/utility/slice.hpp)를 볼 수 있습니다. – CTMacUser