Макрос для замены идентификатора в его аргументе - PullRequest
2 голосов
/ 24 февраля 2020

Мне нужен макрос, который заменяет один идентификатор другим в коде, передаваемом ему в качестве аргумента. Чтобы решить мою задачу, достаточно определить REPLACE_X_WITH_Y, чтобы этот код компилировался:

#define REPLACE_X_WITH_Y(...) __VA_ARGS__ //TODO: replace x with y
int main()
{
    REPLACE_X_WITH_Y(
        int x = 5;
        x = 0;
    );
    return y;
}

Однако было бы лучше иметь обобщенный макрос c REPLACE:

#define REPLACE(x, y, ...) __VA_ARGS__ //TODO: replace x with y
int main()
{
    REPLACE(x, y,
        int x = 5;
        x = 0;
    );
    return y;
}

Возможен ли какой-либо из этих макросов с препроцессором C ++?

Мой реальный пример использования - это эмуляция концепций для одного конкретного случая на старых компиляторах:

#define REQUIRES(...) template<class T_=T, enable_if_t<REPLACE_T_WITH_T_(__VA_ARGS__), int>* = nullptr>

template<typename T> struct S
{
    REQUIRES(is_integral_v<T>) int f(T x) {return 0;}
    REQUIRES(is_floating_point_v<T>) int f(T x) {return 1;}
};

1 Ответ

2 голосов
/ 24 февраля 2020

Я не вижу способа выполнить такую ​​сложную операцию, но в вашем конкретном случае она вам не нужна. Вам нужен зависимый контекст для SFINAE, но он вполне может просто перенести ваше состояние как есть, и t ie его в зависимый бит, над которым у вас есть контроль:

template <class, bool Value>
struct dependent_bool
: std::integral_constant<bool, Value> { };

#define REQUIRES(...)                                       \
    template<                                               \
        class Require_T = void,                             \
        ::std::enable_if_t<                                 \
            dependent_bool<Require_T, (__VA_ARGS__)>::value,\
            int                                             \
        >* = nullptr                                        \
    >

См. это жить на Wandbox

...