pointer to const vs usual pointer (for functions)

佐手、 提交于 2019-12-04 07:49:13

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.

Jagannath

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.

Jesse Vogt

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!