About ## для подключения макроса и вызова различных функций

// file a.h

// #define MY_MACRO( size, name )
MY_MACRO( 1,    var_a )
MY_MACRO( 2,    var_b )
MY_MACRO( 3,    var_b )
MY_MACRO( 4,    var_b )
MY_MACRO( 5,    var_b )
MY_MACRO( 1024, var_c )
// file b.c

#define ARG_1( name ) fun_size_one( name )        // arg with size one
#define ARG_2( name ) fun_size_not_one( name )    // arg with size not one
#define ARG_3( name ) fun_size_not_one( name )    // arg with size not one
#define ARG_4( name ) fun_size_not_one( name )    // arg with size not one
#define ARG_5( name ) fun_size_not_one( name )    // arg with size not one
// #define ARG_...( name ) fun_size_not_one( name )    and so on

#define ARG( size, name ) ARG_##size( name )

/** here is use macro to invoke fun with different size */
#define MY_MACRO( size, name ) ARG( size, name )
#include "a.h"   // to invoke fun_size_one or fun_size_not_one

я должен определить много ARG_1,2,3,4,5... чтобы покрыть разные размеры есть ли способ просто использовать 2 макроса, таких как ARG_ONE и ARG_NOT_ONE, покрывающих этот размер.

В библиотеках препроцессора есть макросы проверки на равенство, поэтому вы можете использовать (или заново изобрести) один из них для проверки на соответствие 1.

chris 14.04.2023 17:15

привет @chris, не могли бы вы привести пример макроса или функции библиотек препроцессора, я изучу и поищу. Спасибо

molly 16.04.2023 08:28

Я имел в виду что-то вроде BOOST_PP_EQUAL как самую прямую функциональность для того, что ваш код делает прямо сейчас. Он будет использоваться с BOOST_PP_IF.

chris 16.04.2023 14:06

привет @chris, я искал библиотеку boost pp и протестировал BOOST_PP_EQUAL, это сработало. Но многие макросы PP имеют ограничение на количество аргументов (возможно, максимум 256), поэтому я думаю, что ответ Эрика - лучший способ решить этот вопрос. Спасибо.

molly 17.04.2023 14:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
//  Replace macro invocation with third argument.
#define Argument3(a, b, c,...)  c

/*  Select third argument, fun_size_not_one, unless x is replaced with a comma,
    which makes fun_size_one the third argument.  (There is a trailing comma
    so that the "..." in Argument3 receives at least one argument, albeit empty.)
*/
#define Auxiliary(x)    Argument3(x, fun_size_one, fun_size_not_one,)

//  Define ARG_1 to be replaced by a comma, to select fun_size_one above.
#define ARG_1 ,

//  Use the Auxiliary macro to select which function is desired.
#define MY_MACRO( size, name ) Auxiliary(ARG_##size) (name)

MY_MACRO( 1,    var_a )
MY_MACRO( 2,    var_b )
MY_MACRO( 3,    var_b )
MY_MACRO( 4,    var_b )
MY_MACRO( 5,    var_b )
MY_MACRO( 1024, var_c )

Полученные результаты:

fun_size_one (var_a)
fun_size_not_one (var_b)
fun_size_not_one (var_b)
fun_size_not_one (var_b)
fun_size_not_one (var_b)
fun_size_not_one (var_c)

Я скомпилировал свой код с помощью вашего метода, вы правы, большое спасибо. Хорошего дня!

molly 14.04.2023 18:06

привет @Eric, Argument3( x, fun_size_one, fun_size_not_one ), без запятой в конце тоже работает, я прав? Используйте Gcc v4.9, "..." получает пустой, кажется, нет предупреждения или ошибки

molly 14.04.2023 18:36

@molly: некоторые компиляторы принимают это, но стандарт C этого не требует, поэтому безопаснее использовать запятую. При программировании не полагайтесь на то, что работает. Используйте спецификации, чтобы узнать, что должно работать.

Eric Postpischil 14.04.2023 18:43

Другие вопросы по теме