2016-10-02 3 views
1

constexpr 및 static_assert를 가지고 놀고 싶습니다. 사실 constexpr 문자열의 길이를 확인해야하는데 이는 전용 함수에 의해 계산됩니다. 여기에 내가 실행하기 위해 노력하고있어 무엇 : 여기constexpr 및 함수 사용

#include <iostream> 
using namespace std; 

class Test 
{ 
    private : 
     static constexpr char str[] = "abc"; 

     static int constexpr constStrLength(const char* str) 
     { 
      return *str ? 1+constStrLength(str+1) : 0; 
     } 
     static constexpr int length = constStrLength(str); 
     static_assert(length ==3, "error"); 

    public : 
     static void f() 
     { 
      cout << len << endl; 
     } 
}; 

int main() 
{ 
    Test::f(); 
    return 0; 
} 

을 그리고 오류가 나는 얻을 수있다 :

error: 'static constexpr int Test::constStrLength(const char*)' called in a constant expression static constexpr int len = constStrLength("length ");

을 달성하기 위해 올바른 방법은 무엇입니까?

도움 주셔서 감사합니다.

+2

문자열은 항상'char str [] = "..."'로 초기화되어 있습니까? 왜냐하면이 폼에서 길이를'sizeof (str) -1'로 간단하게 얻을 수 있기 때문이다. – kennytm

+1

@kennytm : 그렇게하면 잘못된 결과가 발생할 수 있습니다. 예를 들어,'sizeof ("abc \ 0def") -1은'constStrLength()'함수가'3'을 산출하는 동안'7'을 생성합니다. –

+0

내 문자열은 항상 이와 같이 정의되어 있지만 실제로 문자열 내부의 \ 0 문자와 관련된 잘못된 동작을 방지해야합니다. 하지만 팁 주셔서 감사합니다;) –

답변

6

constexpr 기능은 constexpr으로 사용되어야하며, 사용 시점에서 으로 정의되어야합니다.. 당신이 constStrLength()에를 사용할 때,length는 단지 선언 정의 : 클래스 정의 내에서 정의 된 멤버 함수가 실제로 클래스 정의 내에서 만 선언! 그들의 정의는 클래스 정의 직후, 즉 닫는 괄호 바로 뒤에 비공식적으로 사용 가능하게됩니다.

수정 사항은 예를 들어 비 멤버 함수로 사용하거나 기본 클래스에서 정의하여 사용하기 전에 constStrLength()을 정의하는 것입니다.

+0

오, 나는 정적으로 함수를 선언하면 직접 정의했을 것이라고 생각. 내 문제를 해결하는 데 도움을 주셔서 감사합니다. (기본 클래스 해킹을 사용합니다) –

+0

@AntoineMorel : 관련 섹션은 9.2 [class.mem]이라고 생각합니다. 단락 2 : 클래스는 완전히 정의 된 개체 유형 (3.9)으로 간주됩니다 (또는 완전한 타입)을 _class-specifier_의 닫음}에 추가합니다. _member-specification_ 클래스에서 클래스는 함수 본문 내에서 완전한 것으로 간주됩니다. 기본 인수, _using-declarations_ 상속 생성자 소개 (12.9), _exception-specifications_ 및 _brace-or-equal-initializers_ 비 정적 데이터 멤버 (중첩 된 클래스에서 그러한 것들을 포함해서). 그렇지 않으면 자체 클래스 _member-specification_ 내에서 불완전한 것으로 간주됩니다. –

관련 문제