Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing C array to static function declared within a class scope

Tags:

c++

Why in the following example the compiler fails to bind the very same static function if it's declared within a class scope?

#include <vector>
#include <iostream>

struct Foo
{
static constexpr int GetSize()
{
    return 5;
}
static void ProcessArrayWrong(int(&indices)[Foo::GetSize()])
{
    for(int i =0; i < Foo::GetSize(); i++)
    {
        indices[i]++;
    }
}
};

static void ProcessArray(int(&indices)[Foo::GetSize()])
{
    for(int i =0; i < Foo::GetSize(); i++)
    {
        indices[i]++;
    }
}

int main(int argc, char* argv[])
{
    int foo[Foo::GetSize()] = {1,2,3,4,5};

    for(int i =0; i < Foo::GetSize(); i++)
    {
        std::cout << foo[i]++ << std::endl; 
    }
    ProcessArray(foo);
    ProcessArrayWrong(foo); // fails here
    for(int i =0; i < Foo::GetSize(); i++)
    {
        std::cout << foo[i]++ << std::endl; 
    }
    return 0;
}

The error is:

error: non-const lvalue reference to type 'int [*]' cannot bind to a value of unrelated type 'int


It seems that the question linked in the comments is explaining why it's an error. Thanks. It'd be great to know at this point, in regards with the answers provided in the linked post:

  1. Why exactly the "template trick" works? I suspect because template code requires an additional pass to be compiled, but I would rather have a more clear opinion on this.
  2. Is declaring the function has template causing any non wanted or non expected behavior or is it safe to use?
like image 830
Heisenbug Avatar asked Nov 07 '22 08:11

Heisenbug


1 Answers

The “template trick” works because templates (and member functions of class templates) are already instantiated on-demand. While the standard doesn’t actually say that that property allows member functions to be used in things like array sizes, neither is there any actual rule against it in the non-template case and common implementation strategies support the trick as a side benefit.

Given that the current opinion is that the (class) template behavior is more correct, it’s probably safe to rely on it. Moreover, the standard library declares all sorts of things as templates invisibly, indicating that it generally doesn’t cause problems. (You can even use things like explicit instantiations to keep the function template’s definition elsewhere.)

like image 145
Davis Herring Avatar answered Nov 15 '22 05:11

Davis Herring