How can you prevent decay in a function template taking T by value?

arrays, c++, function-templates, templates

Solution

Use the reference type for the parameter

template<typename T> void f(const T& x) 
{
  std::cout << sizeof(T);
}

in which case the array type will not decay.

Similarly, you can also prevent decay in your original version of `f` if you explicitly specify the template agument `T` as a reference-to-array type

f<int (&)[27]>(array);

In your original code sample, forcing the argument `T` to have the array type (i.e. non-reference array type, by using `typeof` or by specifying the type explicitly), will not prevent array type decay. While `T` itself will stand for array type (as you observed), the parameter `x` will still be declared as a pointer and `sizeof x` will still evaluate to pointer size.

Problem

Please consider this code: ``` #include <iostream> template<typename T> void f(T x) { std::cout << sizeof(T) << '\n'; } int main() { int array[27]; f(array); f<decltype(array)>(array); } ``` Editor's Note: the original code used `typeof(array)`, however that is a GCC extension. This will print ``` 8 (or 4) 108 ``` In the first case, the array obviously decays to a pointer and T becomes `int*`. In the second case, T is forced to `int[27]`. Is the order of decay/substitution implementation defined? Is there a more elegant way to force the type to `int[27]`? Besides using std::vector?

Original source

Related problems