views:

138

answers:

3

Silly question, but say you have class Foo:

class Foo
{
public:
    typedef boost::shared_ptr<Foo> RcPtr;

    void non_const_method() {}
    void const_method() const {}
};

Having a const Foo::RcPtr doesn't prevent non-const methods from being invoked on the class, the following will compile:

#include <boost/shared_ptr.hpp>

int main()
{
    const Foo::RcPtr const_foo_ptr(new Foo);
    const_foo_ptr->non_const_method();
    const_foo_ptr->const_method();

    return 0;
}

But naming a typedef ConstRcPtr implies, to me, that the typedef would be

typedef const boost::shared_ptr<Foo> ConstRcPtr;

which is not what I'm interested in. An odder name, but maybe more accurate, is RcPtrConst:

typedef boost::shared_ptr<const Foo> RcPtrConst;

However, Googling for RcPtrConst gets zero hits, so people don't use this as a typedef name :)

Does anyone have any other suggestions?

+3  A: 

The name of a typedef does not represent the syntactical construct used to define its type. The typedef name should convey some of its desired meaning. For example, the Standard defines the names of iterators over const T as const_iterator, even though the iterator itself is not const (you can still increment it). In fact, the whole purpose of an iterator is to change it, in order to iterate over a sequence :)

typedef T const* const_iterator;

For pointers, i personally see little reason to generally typedef them as constant. So the Const in front of the trailing parts could convey the same meaning as the iterators do, and will go with existing practice. So i think it is perfectly fine for you to go and say

typedef boost::shared_ptr<Foo const> ConstRcPtr;

In fact, this is how std::allocator<>::const_pointer is worded too.

Johannes Schaub - litb
+4  A: 

Your statement about where the const goes is right: You need another typedef. In our project, we use Foo::TPtr and Foo::TConstPtr as standard typedefs.

Daniel M.
+1  A: 

naming a typedef ConstRcPtr implies, to me, that the typedef would be typedef const boost::shared_ptr<Foo> ConstRcPtr;

Why does it imply that? When people talk about "const pointers" (as opposed to non-const pointers), they almost always are referring to const char*, not char *const. const_iterator is an iterator-to-const, not an iterator which is const, and I would not be at all surprised that the relationship between ConstRcPtr and RcPtr is the same as the relationship between const_iterator and iterator.

If you need to distinguish between const char* and char *const, then yes, you might call char *const a "const pointer" and const char* a "pointer-to-const". But you almost never do, and so the short phrase "const pointer" is used for the common case. I think that applies here too, unless you're planning to typedef all four of:

boost::shared_ptr<Foo>
boost::shared_ptr<const Foo>
const boost::shared_ptr<Foo>
const boost::shared_ptr<const Foo>

In that case you'll have to be a bit more creative with names.

Steve Jessop
I'm not planning on typedef'ing the const boost::shared_ptr<> itself, since that can be done where the typedef is used. I need the const Foo as an argument type to indicate that the method will not modify the pointed to object.
Blair Zajac