static_assert в макросе, но также расширяется до чего-то, что можно использовать в качестве параметра функции - PullRequest
0 голосов
/ 03 ноября 2018

Например. У меня есть макрос CHARCOUNT(x), который расширяется до sizeof(x)/sizeof(x[0]). Я хотел бы использовать static_assert, чтобы убедиться, что каждое расширение макроса выполняет проверку, чтобы убедиться, что результат больше 2, чтобы избежать передачи кем-либо указателя на строку, а не указателя на массив символов.

Я бы хотел что-то вроде этого статического утверждения:

static_assert(x) > 2

Этот макрос будет использоваться для обеспечения того, чтобы копии строк не превышали размер буфера, например:

TCHAR szMyStr[10];
_tcscpy_s(szMyStr, CHARCOUNT(szMyStr), L"My result");

Если кто-то случайно передаст указатель, где CHARCOUNT приведет к длине указателя на строку вместо числа байтов, которое я хотел бы подтвердить во время компиляции.

const TCHAR* myChars = L"My result";
auto len = CHARCOUNT(myChars);

Приведенное выше CHARCOUNT должно привести к утверждению времени компиляции. Любые указатели будут полезны.

1 Ответ

0 голосов
/ 03 ноября 2018

Вы должны использовать std::extent вместо этого макроса, который дает вам 0 для неподдерживаемых типов (например, массивы без границ, типы без массивов).

Для вашего случая использования лучше подойдет функция constexpr, которая дает вам размер для переменной массива, например:

template <typename T, std::size_t N>
constexpr std::size_t arrsize(T (&)[N]) {
    return N;
}

Тогда вам не нужно указывать размер, поскольку вы можете использовать функцию только с реальными массивами.

...