mockinterface
mockinterface

Reputation: 14860

Explicit decay of an array into a pointer

What is the most concise and idiomatic way of explicitly decaying an array into a pointer?


For example, consider the case where you need to be able to guide SFINAE or be explicit about an overload:

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);

Upvotes: 10

Views: 1459

Answers (3)

Jarod42
Jarod42

Reputation: 217245

You may use one of the following:

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

Upvotes: 9

Nikos Athanasiou
Nikos Athanasiou

Reputation: 31519

The most concise and idiomatic ? I would say taking the address of the first element

foo(&x[0]);

UPDATE

Since c++11 there's a standard way of saying the above:

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

adressof has the following signature

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

and Obtains the actual address of the object or function arg, even in presence of overloaded operator&

Another idea (which also has the advantage of the above) would be to write

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

additionally this works with arrays of incomplete types because it requires no application of [0]

UPDATE 2

Since c++ 14 there's even more explicit functionality on this : std::decay

Upvotes: 5

mockinterface
mockinterface

Reputation: 14860

The stock &x[0] always felt awkward to me because the array in question can be an array of incomplete types, and it is of course invalid to apply a subscript operator to one. Consider this instead,

foo(&*x);

this is only one more characters to type than foo(+x) which is far less readable and harder to grok.

Upvotes: 2

Related Questions