This is mainly a question about a corner of C++ syntax related to fixed-sized arrays.
Suppose I have a function that exploits type information, for example:
template<class T> void fun(T const& t){
std::cout << typeid(t).name() << std::endl;
}
I can pass a value or a temporary object:
int i;
fun(i); // prints "int" ("i" actually)
fun(int{}); // prints "int" ("i" actually)
However I can't do the same with arrays
double a[10][10];
fun(a); // ok, prints "a[10][10]" ("A10_A10_d" actually)
fun(double[10][10]); // doesn't compile
fun(double{}[10][10]); // doesn't compile
fun(double[10][10]{}); // doesn't compile
fun(double()[10][10]); // doesn't compile
fun(double[10][10]()); // doesn't compile
fun(double(&)[10][10]); // doesn't compile
fun(double(*)[10][10]); // doesn't compile
I could in principle do:
typedef double a1010[10][10];
fun(a1010{});
but, is it possible to do without predefining a typedef?
Is it possible at all to construct a fixed sized array in-place as a function argument?
Full code:
template<class T> void fun(T const& t){
std::cout << typeid(t).name() << std::endl;
}
typedef double a1010[10][10];
int main(){
int i;
fun(i); // prints "int" ("i" actually)
double a[10][10];
fun(a); // prints "a[10][10]" ("A10_A10_d" actually)
fun(a1010{});
fun(int{}); // prints "int"
/* fun(double[10][10]); // doesn't compile
fun(double{}[10][10]); // doesn't compile
fun(double[10][10]{}); // doesn't compile
fun(double()[10][10]); // doesn't compile
fun(double[10][10]()); // doesn't compile
fun(double(&)[10][10]); // doesn't compile
fun(double(*)[10][10]); // doesn't compile
*/
return 0;
}
Bonus points (probably a bounty): What about variable-sized arrays?
int N = 10;
f(double[N]);
double) and "numbers" (10, 10) through a single parameter. The contents are never used, it looks like the static array is ever allocated or reserved, because in clang and gcc I was able to pulldouble a [100000000][1000000000]; gun(a); gun((double[100000000][1000000000]){});without stack overflow. I was also hopping that the numbers could be runtime as well.template<class T> struct Tag<T> {}; template<class T> void fun(tag<T>){ std::cout << typeid(T).name() << std::endl; }, so you can pass types easily (no issue with non default constructible type, you might keep rvalue/lvalue constness information, ...). With usage similar tofun(tag<double[10][10]>{});orfun(tag<decltype(var)>{});