У меня есть пара определений в моей программе, которые дают размер массиву. Теперь вы не можете инициализировать массив с размером 0. Поэтому мне нужно проверить это значение, и если он равен нулю, поставьте 1. Я никогда раньше не использовал макрос, но это то, что я придумал:
#define MINIMUMONE(i) do{if(i == 0){return 1;}else{return i;}}while(0)
а затем инициализировать мои массивы так:
int directIn[MINIMUMONE(NRDIRECTINPUTS)] = {0};
с NRDIRECTINPUTS
определенными в отдельном файле. Теперь я получаю ожидаемое первичное выражение ошибки до 'do', ожидаемое '' 'до' do 'и ожидаемое'} 'в конце ввода. Поскольку я раньше не использовал макрос, я в первую очередь не уверен, что это возможно.
Теперь, набрав этот вопрос, я пришел к откровению о том, что это совсем не то, как работают макросы, но они просто заменяют его на то, что приходит после него. Есть ли способ сделать то, что я желаю? Я использую Arduino, поэтому он C/C++, если это может быть полезно.
#define MINIMUMONE(i) ( (i)? (i): 1 )
(i) || 1
, чтобы избежать побочных эффектов , если таковые имеются, с осознанием того, что вы должны оценить i
, по крайней мере один раз, так что любой побочный эффект происходит ровно один раз.
(i) || 1
всегда возвращает 1
, даже если i
было 2
.
Зачем использовать макрос, когда вы можете использовать constexpr
-functions?
constexpr std::size_t minimumone( std::size_t i )
{
return i == 0? 1 : i;
}
Ради комментаторов, это нераспространяемая версия вышеприведенного кода:
constexpr std::size_t minimumone( std::size_t i )
{
return i + (i == 0); // Becomes at least 1 whatever value i has.
}
И, конечно, версия шаблона:
template< std::size_t N >
constexpr std::size_t minimumone()
{
return N == 0? 1 : N;
}
А поскольку С++ 1y, он становится еще лучше:
template< std::size_t N >
std::size_t minimumone = (N == 0? 1 : N);
Здесь версия без условного:
#define MINIMUMONE(i) ((i) + !(i))
MININUMONE
может возвращать переменную вместо константы, в то время как C ++ 03 не поддерживает ее.std::array<T, N>
вместоT[N]
? Они позволяют размер 0.