Используйте имя класса для условного расширения макроса - PullRequest
1 голос
/ 12 февраля 2020

У меня есть функция A , код которой немного изменяется в зависимости от того, является ли входная структура struct B или struct C. Я не хочу писать A дважды, поэтому я инкапсулировал разницу в операторе () структур.

Моя проблема в том, что A обрабатывает много данных, и оператор () называется экстенсивно. Я хотел бы заменить эту часть макросами для повышения производительности моего кода. Примерно так:

#define B_TASK(data) //macro for B's task
#define C_TASK(data) //macro for C's task

struct B();
struct C();

template<class struct_t>
function A(struct_t data){
     //some irrelevant code
     .
     .
     while(..){ //extensive loop
         #if data == B //my original code uses data()
            B_TASK(data)
         #else
            C_TASK(data)
         #endif
     }
}

int main(){
    B b_inst;
    C c_inst;

    A<B>(b_inst);
    A<C>(c_inst);
}

Возможно ли сделать что-то подобное? Я не знаю, как запросить имя структуры в препроцессоре #if.

Ответы [ 2 ]

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

Вы можете использовать constexpr if (C ++ 17) или рефакторинг вашего кода в (хорошо, уже до C ++ 11):

struct B{};
struct C{};


void task(const B& b) {
     // implementation for B's task
}
void task(const C& c) {
     // implementation for C's task
}

template<class struct_t>
void A(struct_t data){
     // code is never irrelevant, comments are
     while(true) { 
         task(data);
         break;
     }
}

int main(){
    B b_inst;
    C c_inst;

    A<B>(b_inst);
    A<C>(c_inst);
}

Я бы никогда не использовал макросы для этой ситуации , У них есть серьезные недостатки, и здесь нет необходимости прибегать к макросам.

PS

#if data == B //my original code uses data()

Как уже упоминалось в комментарии , невозможно установить макрос в зависимости от параметра шаблона, поскольку макросы раскрываются до создания шаблонов.

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

Это возможно, если C ++ 17 constexpr, если , и черта типа std::is_same. Это будет выглядеть как

template<class struct_t>
function A(struct_t data){
     //some irrelevant code
     while(...){ //extensive loop
         if constexpr(std::is_same_v<struct_t, B>)
            B_TASK(data)
         if constexpr(std::is_same_v<struct_t, C>)
            C_TASK(data)
     }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...