Is there any difference between pointer to const and usual pointer for functions? When it is suitable to use const qualifier for stand alone functions?
I wrote short sample to illustrate my question:
#include <iostream>
using namespace std;
int sum( int x, int y ) { return x + y; }
typedef int sum_func( int, int );
int main()
{
const sum_func* sum_func_cptr = ∑ // const function
sum_func* sum_func_ptr = ∑ // non-const function ?
// What is the difference between sum_func_cptr and sum_func_ptr
int x = sum_func_cptr( 2, 2 );
cout << x << endl;
int y = sum_func_ptr( 2, 2 );
cout << y << endl;
sum_func_cptr = 0;
sum_func_ptr = 0;
return 0;
}
g++ gives no warnings. That's why I ask.
Your code is ill-formed with regard to C++03. You can not ever construct a const (or volatile) qualified function type. Whenever you do, your program becomes ill-formed.
This rule has been changed for C++1x, to make the compiler ignore the const
/ volatile
. C++ compilers will usually already implement this rule even in C++03 mode. Thus, the following two will define the same function twice, and results in a compilation error.
typedef void Ft();
void f(Ft const*) { }
void f(Ft *) { } // another definition!
Here is the proof of my claim. C++03, 8.3.5/1
A cv-qualifier-seq shall only be part of the function type for a nonstatic member function, the function type to which a pointer to member refers, or the top-level function type of a function typedef declaration. The effect of a cv-qualifier-seq in a function declarator is not the same as adding cv-qualification on top of the function type, i.e., it does not create a cv-qualified function type. In fact, if at any time in the determination of a type a cv-qualified function type is formed, the program is ill-formed.
Here is that text for C++1x, 8.3.5/7
n2914:
A cv-qualifier-seq shall only be part of the function type for a non-static member function, the function type to which a pointer to member refers, or the top-level function type of a function typedef declaration. The effect of a cv-qualifier-seq in a function declarator is not the same as adding cv-qualification on top of the function type. In the latter case, the cv-qualifiers are ignored.
The above says that the below is valid, though, and creates the function type for a function that can declare a const member function.
typedef void Ft() const;
struct X { Ft cMemFn; };
void X::cMemFn() const { }
Stand alone functions are const by definition. Hence there is no difference between a const and a non-const function pointer.
I think you meant,sum_func* const sum_func_cptr
instead of const sum_func* sum_func_cptr
.
sum_func* const sum_func_cptr = ∑
sum_func* const sum_func_cptr = &sum_new; // will not compile.
// whereas,
const sum_func* sum_func_cptr = ∑ // will compile
const sum_func* sum_func_cptr = &sum_new; // will compile.
sum_func* sum_func_cptr = ∑ // will compile
sum_func* sum_func_cptr = &sum_new; // will compile.
-Jagannath.
As an interesting aside, the const specifier does not seem to have an effect even when used on pointers to member functions.
#include <iostream>
using namespace std;
class Foo {
public:
int sum( int x, int y ) {
_x = x;
_y = y;
return x + y;
}
private:
int _x;
int _y;
};
typedef int (Foo::*sum_func)(int,int);
int main()
{
Foo f;
const sum_func sum_func_cptr = &Foo::sum; // const pointer
sum_func sum_func_ptr = &Foo::sum; // non-const pointer
int x = (f.*sum_func_cptr)( 2, 2 );
cout << x << endl;
int y = (f.*sum_func_ptr)( 2, 2 );
cout << y << endl;
const sum_func* sum_func_cptr_cptr = &sum_func_cptr;
sum_func* sum_func_ptr_ptr = &sum_func_ptr;
x = (f.**sum_func_cptr_cptr)( 2, 2 );
cout << x << endl;
y = (f.**sum_func_ptr_ptr)( 2, 2 );
cout << y << endl;
return 0;
}
I think there has been a basic misunderstanding in the previous replies.
const sum_func sum_func_cptr = &Foo::sum; // const pointer
That means that sum_func_cptr
is a constant pointer to a function, that is you can initialize it with a non-const member function, but you can't change it later to point to another function, because const
refers to the variable.
That's equivalent to:
sum_func const sum_func_cptr = &Foo::sum; // const pointer
Don't you agree? :-)
-Paolo
来源:https://stackoverflow.com/questions/1117873/pointer-to-const-vs-usual-pointer-for-functions