簡體   English   中英

C++ 11,如何在 #if 中使用 const

[英]C++ 11, how to use a const inside an #if

我在我的代碼中使用了一個 const 變量。 並想告訴我的預處理器使用它。 即:

const double x = 1.2;
const bool xIsZero = x==0;

#if xIsZero
...
#endif

但這不起作用。 在 C++ 17 中, if constexpr 但我現在堅持使用 C++11。

因此,我可以使用以下解決方法:

#define X 1.2
#define xIsZero (x==0)
const double x = X;

#if xIsZero
...
#endif

但我只是不喜歡將 x 賦予 #define,我想直接將其賦予常量。 有沒有辦法做到這一點?

如果條件在編譯時已知,則可以使用重載來模擬 C++11 中的if constexpr

void foo(std::true_type) {   // if (xIsZero)
}

void foo(std::false_type) {  // if (!xIsZero)
}

constexpr bool xIsZero = ...;
foo(std::integral_constant<bool, xIsZero>{});

正如LoPiTaL在評論中指出的那樣,這並不完全等同於if constexpr ,因為兩個foo都必須編譯。 當我們使用模板時,這種技術變得很重要。 if兩個分支都使用相同的模板參數集編譯,則使用普通。 通過重載,我們可以有效地丟棄分支。

例如,此代碼失敗:

template<unsigned int i>
void foo(std::integral_constant<unsigned int, i>) {
    if (i > 0) {
        consume_positive_i(i);
        foo(std::integral_constant<unsigned int, i - 1>{});
    } else
        consume_zero_i(i);
}

在 C++17 中,它可以很容易地用if constexpr修復:

template<unsigned int i>
void foo(std::integral_constant<unsigned int, i>) {
    if constexpr (i > 0) {
        consume_positive_i(i);
        foo(std::integral_constant<unsigned int, i - 1>{});
    } else
        consume_zero_i(i);
}

C++11 中的解決方法是重載:

void foo(std::integral_constant<unsigned int, 0>) {   
    consume_zero_i(i);
}

template<unsigned int i>
void foo(std::integral_constant<unsigned int, i>) {
    consume_positive_i(i);
    foo(std::integral_constant<unsigned int, i - 1>{});
}

#if語句是一個預處理器指令。 預處理器在編譯過程之前處理您的代碼。 預處理器甚至不知道您的代碼是什么意思,它實際上可以處理文本。 '#if' 檢查參數是否為真(或定義)並將代碼從#if - #else - #endif語句放入文件。

#define替換您選擇的代碼。 當你輸入時

#define X 1.2
void f() {
    if(X == 0) //...
}

預處理器將其替換為

void f() {
    if(1.2 == 0) //...
}

const是編譯器的關鍵字。 常量是在編譯時定義的,它們被放入內存中的特殊區域。 所以當你輸入

const double x = 1.2;
void f () {
    if(x == 0) //...
}

你從那個記憶中調用x

因此,當您嘗試使用預處理器訪問編譯器處理的區域時,您將獲得所擁有的。

暫無
暫無

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

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