Явный распад массива в указатель

Каков наиболее сжатый и идиоматический способ явного разложения массива в указатель?


Например, рассмотрим случай, когда вам нужно руководствоваться SFINAE или быть явным о перегрузке:

template<typename T, std::size_t N> void foo(T(&x)[N]);
template<typename T>                void foo(T *x); 
//
int x[2] = {0, 1};
foo(x);

Ответ 1

Вы можете использовать одно из следующих действий:

foo(x + 0);
foo(+x);
foo(&x[0]); // assuming operator& has not been overloaded for T
foo(std::addressof(x[0])); // since C++11

Ответ 2

Самый лаконичный и идиоматический? Я бы сказал, беря адрес первого элемента

foo(&x[0]);

UPDATE

Так как С++ 11 существует стандартный способ, говорящий выше:

auto a = std::addressof(x[0]); // a will be * to int

adressof имеет следующую подпись

template<class T> T* addressof(T& arg);

и получает фактический адрес объекта или функции arg, даже при наличии перегруженного оператора &

Другая идея (которая также имеет преимущество выше) заключалась бы в написании

auto a = std::begin(x); // a will be * to int

дополнительно это работает с массивами неполных типов, потому что не требует применения [0]

ОБНОВЛЕНИЕ 2

Так как С++ 14 существует еще более явная функциональность: std::decay

Ответ 3

Запасы &x[0] всегда были для меня неудобными, потому что массив, о котором идет речь, может быть массивом неполных типов, и, конечно, недействительно применять оператор индекса к одному. Вместо этого рассмотрим это,

foo(&*x);

это всего лишь один тип символов, чем foo(+x), который гораздо менее читабельен и сложнее выполнить.