簡體   English   中英

C ++ 17 constexpr字符串解析

[英]C++17 constexpr string parsing

對不起,這將是一個很長的帖子,但我覺得你需要所有的代碼來看看發生了什么。


所以,我一直在嘗試將編譯時字符串轉換為數據結構解析器。 想象一下像正則表達式這樣的東西,其中字符串在編譯時被“編譯”成數據結構但在運行時執行(只要輸入字符串當然是常量)。 但是我遇到了一個我不太明白錯誤的問題:

基本上,我的設計是一個2遍解析器:

  • 傳遞1:確定輸入字符串中有多少“操作碼”
  • 傳遞2:返回一個大小由Pass 1確定的數組,並填入“opcodes”

這是事情的樣子:

// a class to wrap string constants
class constexpr_string {
public:
    template <size_t N>
    constexpr constexpr_string(const char (&s)[N]) : string_(s), size_(N - 1) {}
public:
    constexpr size_t size() const     { return size_; }
    constexpr size_t capacity() const { return size(); }
    constexpr size_t empty() const    { return size() != 0; }
public:
    constexpr char operator[](size_t n) const { return string_[n]; }
private:
    const char *string_;
    size_t      size_;
};

// would have loved to use std::array, but ran into an issue so..
// wrapped in a struct so we can return it
template <class T, size_t N>
struct constexpr_array {
    T array[N] = {};
};

struct opcode { /* not relevant */ };

template <size_t N>
constexpr constexpr_array<opcode, N> compile_string(constexpr_string fmt) {
    constexpr_array<opcode, N> compiled;
    /* fill in compiled_format */
    return compiled;
}

constexpr size_t calculate_size(constexpr_string fmt) {
    size_t size = 0;
    /* calculate size */
    return size;
}

#if 0
// NOTE: Why doesn't **This** work?
constexpr int test(constexpr_string input) {

    constexpr size_t compiled_size = calculate_size(input);
    constexpr auto compiled_format = compile_string<compiled_size>(input);
    return 0;
}
#endif

int main() {
    // NOTE: when this works...
    constexpr char input[] = "...";
    constexpr size_t compiled_size = calculate_size(input);
    constexpr auto compiled = compile_string<compiled_size>(input);
    execute(compiled); // run it!
}

到現在為止還挺好!

當我嘗試將這兩行包裝成函數時出現問題: - /。 我不明白為什么相同的確切代碼在main ,但如果我只是嘗試將相同的constexpr對象傳遞給另一個函數,我開始得到關於不是constexpr事情的錯誤。


這是錯誤消息:

main.cpp: In function ‘constexpr int test(constexpr_string)’:
main.cpp:258:55: error: ‘input’ is not a constant expression
  constexpr size_t compiled_size = calculate_size(input);
                                                       ^
main.cpp:259:70: error: no matching function for call to ‘compile_string<compiled_size>(constexpr_string&)’
  constexpr auto compiled_format = compile_string<compiled_size>(input);
                                                                      ^
main.cpp:60:45: note: candidate: template<long unsigned int N> constexpr constexpr_array<opcode, N> compile_string(constexpr_string)
 constexpr constexpr_array<opcode, N> compile_string(constexpr_string fmt) {
                                             ^~~~~~~~~~~~~~
main.cpp:60:45: note:   template argument deduction/substitution failed:

讓我們減少這個:

constexpr void f(int i) {
    constexpr int j = i; // error
}

int main() {
    constexpr int i = 0;
    constexpr int j = i; // OK
}

函數參數永遠不會是constexpr ,所以if里面不是一個常量表達式,不能用於初始化j 一旦通過函數參數傳遞了某些東西,constexpr-ness就會丟失。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM