2016-10-02 62 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'產生'7',而'constStrLength()'函數產生'3'。 –

+0

我的字符串總是像這樣定義的,但實際上我需要防止在字符串中包含\ 0字符的錯誤行爲。但是,謝謝你的提示;) –

回答

6

A 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或equal_initiators_(包括嵌套類中的這些東西)。否則 它在它自己的類_member-specification_中被認爲是不完整的。 –