Лучшее, что я могу придумать, это:
template <class T, std::size_t N>
char (&sizeof_array(T (&a)[N]))[N];
// As litb noted in comments, you need this overload to handle array rvalues
// correctly (e.g. when array is a member of a struct returned from function),
// since they won't bind to non-const reference in the overload above.
template <class T, std::size_t N>
char (&sizeof_array(const T (&a)[N]))[N];
, который должен использоваться с другим sizeof
:
int main()
{
int a[10];
int n = sizeof(sizeof_array(a));
std::cout << n << std::endl;
}
[EDIT]
Если подумать, я считаю, что это невозможно сделать за один «функциональный вызов» в C ++ 03, кроме макросов, и вот почему.
С одной стороны, вам явно понадобится вычет параметра шаблона для получения размера массива (либо напрямую, либо через sizeof
, как вы делаете). Однако вывод параметров шаблона применим только к функциям, а не к классам; т. е. у вас может быть параметр шаблона R типа ссылка на массив-из-N, где N - это другой параметр шаблона, но вам нужно будет указать и R, и N в точке вызова; если вы хотите вывести N из R, это может сделать только вызов функции.
С другой стороны, единственный способ, которым любое выражение, связанное с вызовом функции, может быть постоянным, - это когда он находится внутри sizeof
. Все остальное (например, доступ к статическому члену или члену enum по возвращаемому значению функции) все еще требует вызова функции, что, очевидно, означает, что это не будет постоянным выражением.