2013-06-06 2 views
0

ArrayCount가 템플릿 일 때 clang과 gcc가 아래 코드를 컴파일하지 못합니다. 이것은 특히 ArrayCount 솔루션의 sizeof 작업에 비추어 잘못된 것 같습니다. ArrayCount의 템플릿 버전은 일반적으로 더 나은 솔루션입니다.하지만 여기까지가는 중입니다. constexpr은 겉으로보기에는 약속의 정신에 부합하지 않습니다.constexpr 템플릿 함수가 구성원 배열 크기를 const 식으로 표시하지 않습니다.

#if 1 
    template<typename T, size_t N> 
    constexpr size_t ArrayCount(T (&)[N]) 
    { 
     return N; 
    } 
    // Results in this (clang): error : static_assert expression is not an integral constant expression 
    // Results in this (gcc): error: non-constant condition for static assertion, 'this' is not a constant expression 
#else 
    #define ArrayCount(t) (sizeof(t)/sizeof(t[0])) 
    // Succeeds 
#endif 

struct X 
{ 
    int x[4]; 
    X() { static_assert(ArrayCount(x) == 4, "should never fail"); } 
}; 
+0

연타/GCC 버전? 어느 stdlib? – Xeo

답변

1

그것은이 코드가 ArrayCount는 비 constexpr 인수를 복용 함수이기 때문에 컴파일 실패 나에게 의미가 있습니다. 표준에 따르면, 이것은 ArrayCount이 비 constexpr 기능으로 intstantiated되어야한다는 것을 의미합니다 믿습니다.

물론 해결 방법이 있습니다.

template<typename T> struct ArrayCount; 
template<typename T, size_t N> 
struct ArrayCount<T[N]> { 
    static size_t const size = N; 
}; 

template<typename T> 
constexpr size_t ArrayCount2() { 
    return ArrayCount<T>::size; 
} 

struct X { 
    int x[4]; 
    X() { 
     static_assert(ArrayCount<decltype(x)>::size == 4, "should never fail"); 
     static_assert(ArrayCount2<decltype(x)>() == 4, "should never fail"); 
    } 
}; 
그것은 당신이하고자하지 않을 수 있습니다 때 decltype()를 사용하는 것을 의미 않지만, 휴식 않습니다

프로 견적 : 나는 (다른 측면에서 구현 한) 내 머리 위로 떨어져 두 가지를 생각할 수 비 constexpr 매개 변수를 가져 오는 데 대한 제약 조건.

2
적합한 솔루션이 사제 코드를 사용하지 않는

하지만, 단순한 유형의 특성 :

int a[] = {1, 2, 3}; 

#include <type_traits> 

static_assert(std::extent<decltype(a)>::value == 3, "You won't see this");