부름

2017-02-09 17 views
1

이 코드 고려 컴파일 실패부름

error: ‘* & xx’ is not a constant expression 
note: in template argument for type ‘int’ 

다음 main() 함수에서

#include <array> 

template < int... Ints > 
constexpr std::array<int,sizeof...(Ints)> theIntArray = {Ints...}; 

template < size_t NN > 
constexpr void test(const std::array<int,NN>& xx) 
{ 
    theIntArray<xx[0]>; 
} 

constexpr std::array<int,2> aa = {10,20}; 

int main() 
{ 
    theIntArray<aa[0]>; // passes 
    test(aa); // FAILS ?! 

    return 0; 
} 

을 두번째 라인 이상한 오류 메시지와 함께 실패 동안 첫번째 라인 패스 gcc-7.0.1을 사용 중이고 라이브 예제 here을 찾을 수 있습니다.

표준에 따른 것입니까, 아니면 버그입니까? 첫 번째 라인이 통과하는 동안 두 번째 라인이 실패하게 만드는 것은 무엇입니까?

답변

2

모든 constexpr 함수는 constexprconstexpr 인수와 함께 유효해야합니다. 즉, constexpr 함수의 인수는 본문 내에 constexpr이 아니지만 함수 본문 외부에있는 constexpr 인 경우 함수에 따라 certian 계산이 constexpr이 될 수 있습니다. xx[0]constexpr이지만 기능 체 내에 xx하지constexpr 경우

theIntArray<xx[0]>; 

에만 유효한 구문이다.

template < size_t NN, std::array<int,NN> const& xx > 
constexpr void test() 
{ 
    theIntArray<xx[0]>; 
} 

live example.

+0

TIL 리터럴 형식에 const-reference를 추가하여 사용자 정의 형식이 아닌 템플릿 매개 변수를 모방합니다. upvoted. – TemplateRex

1

차이점은 constexpr 함수 매개 변수가 존재하지 않는다는 것입니다. 즉,

constexpr auto fun(int x) { 
    constexpr y = x; 
    return y; 
} 

을 할 수 있고 어느 쪽도 아니 당신은 함수 내에서 비 ​​형 템플릿 매개 변수로 함수 매개 변수 xx[0]을 사용할 수 없습니다. aa[0]은 기능 밖에서 평가되기 때문에 다릅니다.

원하는 것을 수행하는 유일한 방법은 함수 매개 변수를 형식이 아닌 템플릿 매개 변수로 만드는 것입니다. 이를 수행하려면 @Yakk의 응답을 참조하십시오. 여기서 그는 constexpr 배열에 대한 const 참조를 비 유형 템플릿 매개 변수로 사용합니다.