2016-12-21 1 views
0

Мой код настраивается с помощью макросов определения. Для того, чтобы получить значение в коде, я делаю это:Как получить логическое значение, указывающее, определен ли макрос или нет?

#ifdef CONFIG_X 
static constexpr bool x = true; 
#else 
static constexpr bool x = false; 
#endif 

Но это быстро становится очень некрасиво в коде с несколькими переменной конфигурацией ...

Другим решением я нашел просто вырезать код в двух случаях:

#ifdef CONFIG_X 
#define CONFIG_X_BOOL true 
#else 
#define CONFIG_X_BOOL false 
#endif 

static constexpr bool x = CONFIG_X_BOOL; 

Это немного лучше, но не очень приятно.

Есть ли хороший способ иметь логическое значение или 1 или 0, если макрос определен?

+0

AFAIK no. но C++ 17 представит constexpr if, что означает оператор if, который оценивается только во время компиляции. возможно, это опция –

+0

К сожалению, это не поможет в этом случае, так как я не смогу выполнить '' 'if constexpr (MACRO)' '', если макрос не определен :( –

+0

Почему бы просто не поставить зависимый код в блоках if и else? – NathanOliver

ответ

1

Это возможно, но только в ограниченном случае, когда вы ищете пустые определяет (как это часто бывает с флагами компиляции) или где вы знаете диапазон способов определения флага, например, с помощью 0 или 1.

Вот рабочий код:

#include <iostream> 

// Define two genetic macros 
#define SECOND_ARG(A,B,...) B 
#define CONCAT2(A,B) A ## B 

// If a macro is detected, add an arg, so the second one will be 1. 
#define DETECT_EXIST_TRUE ~,1 

// DETECT_EXIST merely concats a converted macro to the end of DETECT_EXIST_TRUE. 
// If empty, DETECT_EXIST_TRUE converts fine. If not 0 remains second argument. 
#define DETECT_EXIST(X) DETECT_EXIST_IMPL(CONCAT2(DETECT_EXIST_TRUE,X), 0, ~) 
#define DETECT_EXIST_IMPL(...) SECOND_ARG(__VA_ARGS__) 

// We will create MY_DEFINE, but not MY_DEFINE2 
#define MY_DEFINE 

int main() 
{ 
    // We can now use DETECT_EXIST to detect defines. 
    std::cout << "MY_DEFINE = " << DETECT_EXIST(MY_DEFINE) << std::endl; 
    std::cout << "MY_DEFINE2 = " << DETECT_EXIST(MY_DEFINE2) << std::endl; 
} 

Этот код будет производить вывод:

MY_DEFINE = 1 
MY_DEFINE2 = 0 

Так как первый действительно существует, а второй делает нет.

Если макрос установлен в значение, такое как 1, вам просто нужно иметь альтернативную версию DETECT_EXIST_TRUE, чтобы обработать ее, с макроснимком, вставленным в конец. Например:

#define DETECT_EXIST_TRUE1 ~,1 

Тогда, если у вас есть:

#define MY_DEFINE1 1 

код, как это будет работать правильно в основной:

std::cout << "MY_DEFINE1 = " << DETECT_EXIST(MY_DEFINE1) << std::endl; 
1
#ifndef CONFIG_X 
    #error "Written for config x" 
    #endif 


    // True for config x, hack this about for other configurations 
    static bool x = 1; 

Теперь он распадается, если конфигурация не х , Как правило, это лучше, чем пытаться догадаться, что потребует неназванная конфигурация, которая не является X.

+0

Я не хочу ломаться, если конфиг не определен, это то, что мне нужно поддержать. –

Смежные вопросы