Если базовая стандартная библиотека C поддерживает «Расширения с плавающей запятой, часть 1» (ИСО / МЭК TS 18661-1: 2014) , то у вас есть доступные макросы препроцессора, которые можно использовать для идентификацииразмеры типов:
#include<climits>
#include<cstdint>
void myfunc(unsigned o);
#if UINT_WIDTH != SIZE_WIDTH
void myfunc(size_t o);
#endif
Это поддерживается, например, glibc.Помните, что тест всегда завершается неудачей, если макросы не определены, т. Е. Если спецификация не реализована, поэтому вам, вероятно, следует также проверить это, то есть
#if UINT_WIDTH != SIZE_WIDTH || !defined(UINT_WIDTH) || !defined(SIZE_WIDTH)
Без таких макросов, определяемых реализацией, препроцессорне может быть использован для достижения того, что вы хотите, так как он фактически не знает о типах C или C ++.
Любое решение на уровне компиляции C ++ потребует от вас хотя бы некоторой модификации объявлений функций.
Я не считаю это решение особенно чистым, но ваше текущее решение также не является.Действительно, если, как я подозреваю, цель состоит в том, чтобы избежать определенных неявных преобразований, метод должен представлять собой шаблон с static_assert
, ограничивающим тип соответствующим образом.
Редактировать:
Приведенный выше код работает как есть с текущими glibc и gcc, но я не уверен, технически ли это правильно.Это техническая спецификация, расширяющая C11, а не C ++.Я не знаю, как и включает ли C ++ их, или они будут считаться расширениями, определяемыми реализацией.
Также согласно спецификации макросы должны быть определены, только если вы
#define __STDC_WANT_IEC_60559_BFP_EXT__
до первого #include<stdint.h>
или #include<limits.h>
.При компиляции в режиме C GCC с glibc действительно требует этого.
Можно ли проверить, реализована ли спецификация, сравнив макрос __STDC_IEC_60559_BFP__
с 201ymmL
.Однако GCC с glibc, похоже, не устанавливает этот макрос, и в документации отмечается, что поддержка спецификации является лишь частичной.
Вероятно, вы должны по крайней мере убедиться, что UINT_WIDTH
и SIZE_WIDTH
установлены, прежде чем доверятьсравнение сделано выше.Если это не так, например, из-за того, что спецификация не поддерживается, всегда будет оцениваться как 0 != 0
, то есть false
.