Declaration Help?

closed account (zb0S216C)
I've got a bit of an issue with my function. I'm trying to return a constant reference to a pointer. The target pointer is a non-constant data member (pointer, obviously) within my class. however, according to VC++, this declaration of my function is incorrect:

const int *&AcquirePtr( ) const;

VC++ reacts with this message: 'return' : cannot convert from 'int *const ' to 'const int *&'

So I changed my declaration to this:

int * const &AcquirePtr( ) const;

VC++ prefers this declaration instead of the previous one. The thing is, I've never seen this type of declaration before. I first interpreted this function as: Reference to a constant-pointer-to-an-int. Strangely enough, the pointer I'm returning isn't even constant, as I've said before.

I'm wrong on this one, I know it.

Ideas?

Wazzak
Reference to const pointer to int sounds right. How is that pointer not constant?
closed account (zb0S216C)
It's confusing the hell outta me. The pointer needs to be constant so does the function, otherwise, the const qualifier of my copy constructor is dropped, which of course, isn't allowed and produces and error.

I did once again move the const until it was after the ampersand. I thought it would change the function declaration to this: Constant reference to a pointer-to-an-int. But no. According to VC++, the const is ignored, thus rendering the returned reference non-constant, again, drops the const qualifier of the copy constructor.

I'm really puzzled with this issue.

Wazzak
const int *& reference to a non_constant pointer to constant integer

int * const & reference to a constant pointer to non_constant integer




note that references are constant so a const on a reference is redundant.

int & const int_ref ; //const modifier here is redundant - will be ignored by compiler
Last edited on
What you found is not strange and it makes sense.

First of all, we have to understand that "const int *" and "int * const".

In another format, it looks like:

1. "const (int *)" : means "constant pointee"
2. "(int *) const" : means "constant pointer"

Then we add "&" on them:

1. "constant pointee" & : means "reference to constant pointee"
2. "constant pointer" & : means "reference to constant pointer"

Then let's see return:

1.
1
2
3
4
5
6
const int * & func()
{
    const int * p1 = &i; // i is defined somewhere
    int * p2 = &i; // return p2 will fail as compiler can only cast it to "int * const"
    return p1; // good
}


2.
1
2
3
4
5
6
int * const & func()
{
    const int * p1 = &i; // return p1 will fail as compiler cannot remove const to get "int *"
    int * p2 = &i;
    return p2; // good as compiler can cast it to "int * const"
}


So syntax "int * const & func()" makes sense now.

For sure, the following examples are good and don't have difference as MyClass is not pointer

class MyClass;
const MyClass func();
MyClass const func();
Last edited on
closed account (zb0S216C)
guestgulkan wrote:
note that references are constant so a const on a reference is redundant. (sic)

Noted. Thanks for that information, Guestgulkan.

Thanks for your reply, Eric. In your examples, you're returning a constant pointer, but the pointer I'm trying to return is non-constant. I see how you've created a new pointer that points to another previously defined variable, and how it works, but the example differs from my problem. p1 would have to be a pointer-to-a-pointer, and with the additional 4 bytes on the stack.

I'll give a quick overview of my classes purpose: The class acts as an interface for an array. The array is a dynamically allocated region of memory that can be rebuilt at the clients request, which means de-allocating then re-allocating memory. Having a constant pointer to a region of memory wouldn't work since that would restrict the client from re-building to array to a different length.

Here's my class (stripped of the non-associated members):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template < typename TypeSpec >
class Array
{
    private:
        TypeSpec *Region;
 
    public:
        TypeSpec * const &AcquirePtr( ) const;
};

template < typename TypeSpec >
TypeSpec * const &Array< TypeSpec >::AcquirePtr( ) const
{
    return this->Region; // VC++ doesn't like this. Cannot convert.
}


Wazzak
Last edited on
In your examples, you're returning a constant pointer, but the pointer I'm trying to return is non-constant.

No, In my example 2, I am returning p2 which is non-const pointer, and compiler casts it to reference to const pointer.

EDIT:
p1 would have to be a pointer-to-a-pointer, and with the additional 4 bytes on the stack.

But in your code above, I don't see you are returning a pointer's pointer. this->Region is just a pointer if TypeSpec is not a pointer.
But again, if TypeSpec is "int *" for example, this->Region will be int **, then it doesn't match with the return type "int *".
So I guess, do you want to change the code like:
1
2
3
template < typename TypeSpec >
TypeSpec * const &Array< TypeSpec >::AcquirePtr( ) const
Last edited on
closed account (zb0S216C)
EricDu wrote:
But again, if TypeSpec is "int *" for example, this->Region will be int **, then it doesn't match with the return type "int *". (sic)

The method will still work. If TypeSpec is of type pointer, then Array::Region will be a pointer-to-a-pointer. This is the same for Array::AcquirePrt( ) but I'll be returning it as a reference to a pointer-to-a-pointer.

Thanks for helping either way, Eric :) Thanks to everyone who helped me :) I understand how it works now! :)P

Wazzak
Last edited on
Topic archived. No new replies allowed.