Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't C++ infer array size with offset?

Tags:

c++

This code fails to compile

template<unsigned n>
void test(char const (*)[n + 1]) { }

int main()
{
    char const arr[] = "Hi";
    test(&arr);
}

with error

note: candidate template ignored: couldn't infer template argument 'n'

However, if you change n + 1 to n, it compiles just fine.

Why can't the compiler deduce n when it has an offset added to it?

like image 816
user541686 Avatar asked Oct 02 '21 19:10

user541686


People also ask

How to use offset () with dynamic arrays?

how to use OFFSET () with it does not address a range that uses Dynamic Arrays In the following screenshot you can see the first table and the OFFSET () range that uses Dynamic Arrays AND the SPILL Range Operator The formula in cell L16 is =OFFSET (E16#,0,-1,M14,M13) and E16# is the SPILL Range Operator.

How to find the size of an array Using sizeof operator?

Using sizeof directly to find the size of arrays can result in an error in the code, as array parameters are treated as pointers. Consider the below program. Explanation: This code generates an error as the function fun () receives an array parameter ‘arr []’ and tries to find out the number of elements in arr [] using sizeof operator.

What is the reference of the Offset () function?

The second range, using ordinary, non Dynamic Array functions, gives exactly the same answer and yet this version of the OFFSET () function uses the reference of E29 rather than the reference E15# used by the first OFFSET () example.

Can variable sized arrays be initialized in C?

But, unlike the normal arrays, variable sized arrays cannot be initialized. For example, the following program compiles and runs fine on a C99 compatible compiler. But the following fails with compilation error.


Video Answer


1 Answers

From cppreference, in the " Non-deduced contexts" section:

In the following cases, the types, templates, and non-type values that are used to compose P do not participate in template argument deduction, but instead use the template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.

(...)

  1. A non-type template argument or an array bound in which a subexpression references a template parameter:
template<std::size_t N> void f(std::array<int, 2 * N> a);
std::array<int, 10> a;
f(a); // P = std::array<int, 2 * N>, A = std::array<int, 10>:
      // 2 * N is non-deduced context, N cannot be deduced
      // note: f(std::array<int, N> a) would be able to deduce N 

(...)

In any case, if any part of a type name is non-deduced, the entire type name is non-deduced context. (...)

Because n + 1 is a subexpresion, the whole context then cannot be deduced.

like image 83
ShadowMitia Avatar answered Nov 14 '22 22:11

ShadowMitia