This question already has answers here:
Pointer to member function - syntax
(2 answers)
Closed last year.
class C{
public:
int i(){return 3;}
};
void memfn(int (C::* const & func)()){}
void fn(int (* const & func)()){}
int main() {
fn(&foo); //Works
fn(foo); //Works
memfn(&C::i); //Works
memfn(C::i); //Doesn't Work
}
When passing a function pointer as a parameter, the address-of operator is optional on the function. Why does it not work if removed on a member function?
There is an implicit conversion from global function references, or static member function references, or non-capturing lambdas, to function pointers. This is for capability with C.
But such implicit reference-to-pointer conversions are not for non-static member functions (and capturing lambdas!), because they need an implicitly passed this pointer to work, the conversion just lacks that thing.
In your case, if we make i() static, then it can be passed to fn either by reference or by address.
Related
This question already has an answer here:
c++ - const member func, that can be called upon lvalue instances only, using a ref-qualifier
(1 answer)
Closed 2 years ago.
For the following code:
class C
{
public:
void fun() const {};
void fun() const & {};
};
I know that this is illegal, since we cannot overload with const and const &. However, my question is: we already have const member function in the old standard, why did we need to introduce the const & member function? Are there any semantic differences between a const member function and a const-ref member function?
What's the difference between const member function and const-ref member function
Lvalue ref qualified function cannot be called on rvalue instance arguments (unless the function is also const qualified). Unqualified member functions can be.
This question already has answers here:
Why can a const method take a non const reference?
(2 answers)
Closed 2 years ago.
Consider the following code:
#include <iostream>
class ObjectCalculator {
public:
struct Object {
int id = 0;
};
void setObject(Object& object) const {
object.id = 1;
}
Object m_object;
};
int main() {
ObjectCalculator objCalc{};
std::cout << objCalc.m_object.id << std::endl;
objCalc.setObject(objCalc.m_object);
std::cout << objCalc.m_object.id << std::endl;
return 0;
}
I thought this this line should throw an error during compilation since the internal variable is changed via const method setObject:
objCalc.setObject(objCalc.m_object);
but the code compiles with no errors and outputs:
0
1
Could you please clarify why const does not have effect in this case?
const related to the members of the class.
You modifying the method argument, so it can be changed, regardless of const.
const after method applied to the implicit first method argument this, through which all class members accessed.
cppreference
A non-static member function can be declared with a const, volatile,
or const volatile qualifier (this qualifier appears after the
parameter list in the function declaration). Differently cv-qualified
functions have different types and so may overload each other.
In the body of a cv-qualified function, the this pointer is
cv-qualified, e.g. in a const member function, only other const member
functions may be called normally. (A non-const member function may
still be called if const_cast is applied or through an access path
that does not involve this.)
The const qualifier is to tell that the function does not modify this object.
By passing the object to modify as an argument you don't modify this, you modify the object passed as an argument.
If you tried to modify m_object in the function, you would get the error you expected.
This question already has answers here:
Why is this call to member function ambiguous?
(3 answers)
Closed 5 years ago.
struct A
{
void fn(double a) const {}
void fn(int a){}
};
int main()
{
A().fn(1.);
}
For the above mentioned function why does the compiler produce an ambiguity; Both the types are different.
Why would you like to pass an int only to a non-const A?
There are two parameters to each member function, this and a. So you require a const A* for this and doublefor a, or non-const A* and int.
And the call doesn't fully match either alternative, as you have non-const Aand double. So the compiler can either convert A() to const A, or doubleto int. And it cannot decide which is the best.
This question already has answers here:
C++ - Why static member function can't be created with 'const' qualifier
(5 answers)
C++ : Why cant static functions be declared as const or volatile or const volatile [duplicate]
(4 answers)
Closed 3 months ago.
This is the error:
error: static member function ‘static void myClass::myfunct()’ cannot have cv-qualifier
Can someone please explain this error and why const cannot be used.
#include<iostream>
class myClass{
static void myfunct() const
{
//do something
}
};
int main()
{
//some code
return 0;
}
Worth quoting the standard here
9.4.1 Static member functions
2) [ Note: A static member function does not have a this pointer (9.3.2). —end note ] A static member
function shall not be virtual. There shall not be a static and a non-static member function with the
same name and the same parameter types (13.1).
A static member function shall not be declared const,
volatile, or const volatile.
static functions have no this parameter. They need no cv-qualifiers.
See this answer by James McNellis
When you apply the const qualifier to a nonstatic member function,
it affects the this pointer. For a const-qualified member function
of class C, the this pointer is of type C const*, whereas for a
member function that is not const-qualified, the this pointer is of
type C*.
A static member function is not bound to an instance of its class, so it does not make sense for it to be const and/or volatile (i.e. "cv-qualified"), because there is no instance to which const or volatile can be applied to in calling that function.
It doesn't make sense to write const there, because the function is static and therefore there is no class instance on which to imbue a const context. Thus it is treated as an error.
Qualifier const in a member function declaration is applied to the pointer to the object of class this. As static functions are not bound to objects of the class they have no implicit parameter this. So the qualifier const has no any sense for these functions.
Const qualifier for member functions means that the function will not change the object instance and can be called on const objects. Static member functions are not bound to any object instance and therefore it makes no sense for them to be const, since you don't call the static member function on any object. That is why the standard forbids it.
class Foo
{
public:
void memberFunc();
static void staticMemberFunc();
}
Foo f;
f.memberFunc(); // called on an object instance
Foo::staticMemberFunc(); // not called on an object instance
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How does dereferencing of a function pointer happen?
If we have
void f() {
printf("called");
}
Then the following code will result in output of "calledcalled":
f();
(*f)();
I don't really understand how this works…what is the difference between *f and f? And why would you call a function using the latter syntax?
There are two ways to call a function in C++:
By name:
f();
Through a function pointer:
typedef void (*fptr_t)();
fptr_t fptr = &f;
(*fptr)();
Now, using the address-of operator on a function name (&f) obviously creates a function pointer. But the function name can implicitly convert to a function pointer when certain conditions are met. So the above code could be written as:
typedef void (*fptr_t)();
fptr_t fptr = f; // no address-of operator, implicit conversion
(*fptr)();
Your second example is doing exactly this, but using a temporary variable to hold the function pointer instead of a named local variable.
I prefer to use address-of when creating function pointers, the meaning is much clearer.
A related note: The function call operator will automatically dereference a function pointer if one is provided. So this also is legal:
typedef void (*fptr_t)();
fptr_t fptr = &f;
fptr();
That's pretty useful with templates, because the same syntax works whether you have a function pointer or a functor (object implementing operator()) passed in.
And neither shortcut works with pointer-to-members, there you NEED explicit address-of and dereference operators.
In C, #Mehrdad explains that all function calls use a function pointer.
The first one is somewhat of a syntactic sugar for the second one. The second one makes it obvious that you're making the call through a pointer, and it's used mainly with function pointers rather than regular functions, to make the distinction more obvious.
Just as an array type is almost entirely equivalent to the corresponding pointer-to-element type, a function type is entirely equivalent to the corresponding pointer-to-function type:
void (*func1)() = f; // function type -> pointer-to-function type
void (*func2)() = &f; // pointer-to-function type -> pointer-to-function type
and also
void (*func)() = ...;
func(); // pointer-to-function type + function-call operator
(*func)(); // function type + function-call operator
So, in
(*f)();
you're dereferencing f (implicitly converted to &f), and then apply the function-call operator.