This question already has answers here:
determine size of array if passed to function
(10 answers)
Closed 4 years ago.
Suppose I have a function like this:
void MyFun(MyClass* p){
}
Where p is actually an unknown length array. How can I overloaded it to accept an array of rvalue MyClass.
Basically, you cannot - since being an rvalue is not really a proper part of the type system. There's no "pointer to rvalue T" or anything like that. Also, because using a pointer means that the pointed-to object could be any subclass of MyValue (that is also a reason I would not try something like reinterpreting the pointer as an std::array<MyClass, 123>, even if I knew the length to be 123).
I suggest you wrap your raw array in some class (dumb name for it: BunchOfMyClasses), and have:
void MyFun(const BunchOfMyClasses &);
void MyFun(BunchOfMyClasses &&);
as the overloads.
Related
This question already has answers here:
How can I pass a member function where a free function is expected?
(9 answers)
How can I pass a member function pointer into a function that takes a regular function pointer?
(4 answers)
Closed 9 months ago.
I'm having problems casting a function pointer.
It works (no cast needed) outside a class.
Here is the signature of the function I'm calling.
Result* FancyClass::callMe(void(*functionPointer)())
It works with.
void defaultState()
{
//
}
// ..
Result *result= instance.callMe(defaultState);
But it does not work with
void MyClass::defaultState()
{
//
}
// ..
Result *result= instance.callMe(MyClass::defaultState);
I am getting this:
argument of type "void (MyClass::)()" is incompatible with parameter of type "void ()()"
How to cast this correctly?
You can't cast it correctly, because pointers to member functions are different from pointers to regular functions. For starters, you must write &MyClass::defaultState, and the parameter has to be of type void(*MyClass::functionPointer)()
You can't even store &MyClass::defaultState directly in a std::function<void()>. What object would you call it on? But you could bind an instance, and store the bound result in a std::function<void()>.
The question was tagged "C", but C doesn't understand classes and can't call member functions.
This question already has answers here:
Why does argument matching in C++ ignore array sizes?
(1 answer)
In a function declaration, what does passing a fixed size array signify? [duplicate]
(3 answers)
Why can one specify the size of an array in a function parameter?
(3 answers)
Closed 3 years ago.
In C++, arrays are supposed to be passed to functions by reference. Hence, in what follows, function foo should implicitly use array inp by reference.
void foo(double inp[10]) {}
void foo1(double (&inp)[10]) {}
My question is, since both functions supposedly have the same interpretation of the input variable, why can we call foo in what follows, but we cannot call foo1?
int main()
{
double ary[20];
foo(ary); // compiles without any problem.
foo1(ary); // compiler error: invalid initialization of reference of type ‘double (&)[10]’ from expression of type ‘double [20]’
return 0;
}
since both functions supposedly have the same interpretation of the input variable
But they don't. A function argument of the type double inp[10] is automatically adjusted to a pointer double*. The 10 plays no part in providing type information here. Since all arrays decay to pointers, that will allow you to pass an array of any size.
A reference to an array does not get adjusted however. The type information is still there, and it must be a reference to an array of exactly ten doubles. The only way to pass a reference to an array of any size is to have a separate function for it, which you may write a function template to accomplish
template<std::size_t N>
void foo2(double (&inp)[N]) {}
This question already has answers here:
Passing references to pointers in C++
(10 answers)
Closed 4 years ago.
I have two function signatures in C++
void printArray(int* arrayPtr);
void printArray(int*& arrayPtr);
I understand the 1st function. It says the function takes in a arrayPtr argument which is of type that's a pointer pointing to an integer.
Both function signature works, but I have a hard time understanding the 2nd signature(*&) and what benefits it offers?
It's exactly the same as type versus type&; the first is a value and the second is a reference. The fact that type is a pointer doesn't change that.
This question already has answers here:
what does this mean char (*(*a[4])())[5]?
(4 answers)
Closed 7 years ago.
Can somebody explain what does it mean?
void f(int (*)[7]) {}
There is a site devoted to dealing with C gibberish and converting it to English:
cdecl.org Try it) It is convenient and sometimes even entertaining.
It states that void f(int (*)[7]) means: declare f as function (pointer to array 7 of int) returning void.
This is a function definition, which can accept a pointer to an array of int with 7 size.
Declare an 7-size array, int a[7];, and you can pass the address of it into f, like f(&a);
Check the live: http://cpp.sh/8ztz
It's definition of function that takes one parameter. That parameter is an unnamed pointer to array of ints.
This question already has answers here:
When a function has a specific-size array parameter, why is it replaced with a pointer?
(3 answers)
Closed 9 years ago.
I'm just curious what is the reason for the following error: I'm trying to determine the size of an integer array.
When I find the size of array in main function, this code returns correctly:
int program[12] = { 1007, 1008, 2007, 3008, 2109, 1109, 4300, 0, 0, 0, -99999 };
cout<<sizeof(program)/sizeof(program[0])<<"\n";
But if I pass program to a function by value, it always return 2:
void Sipmletron::load(int program[])
{
int length=sizeof(program)/sizeof(program[0])
std::cout<<length<<"\n";
memory= new int[length];
}
You cannot pass arrays by value. The argument is passed as a pointer to the first element of the array, so you are in effect calculating sizeof(int*) / sizeof(int).
When an array is passed in C++ (and in C), it looses it's size (it's passed as the address of the first element, no matter whether it is int * or int []).
You can use std::array if you are using C++11, which has a size() member function, similar to vector. In almost all other aspects, it is the same as a standard C style array.
Otherwise, you have to pass the size along with the array - or use some marker to indicate the end (looks like you already have that with -99999).
There are two special-case language rules at play here, both inherited directly from C.
An expression of array type, in most contexts, is implicitly converted to ("decays to") a pointer to the array's first element. The exceptions in C are when the expression is the operand of unary & or sizeof, or when it's a string literal in an initializer used to initialize an array (sub)object. C++ has more exceptions, but none that apply here.
A parameter defined as some_type foo[] is "adjusted" to some_type *foo, so your parameter program is really a pointer, not an array. (This adjustment occurs only for parameter declarations.)
These rules (unfortunately IMHO) work together to make it appear that you're passing an array object by value, and accessing an array inside your function, but in fact it's all pointers.
You could do this with templated member functions if you really wanted to:
template <size_t N>
void Sipmletron::load(int (&program)[N])
{
size_t length = N;
std::cout << length << "\n";
memory = new int[length];
}
In addition, and even without seeing the rest of your code, I'm feel sure it would be worth your while looking at using a std::vector instead of doing your own memory management using new, with a more idiomatic load(...) that used iterators.