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:
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With