J
jason.cipriani
Here is a program, it looks weird but it models what I'm trying to do.
In this program:
- "Object" is just some example type.
- "Container" holds a single item of some type, but provides access
access to a copy of that object only via a nested class
Container::ContainedItem.
=== BEGIN ===
// An example object with a member function.
class Object {
public:
void function () const { }
};
template <typename T> class Container {
private:
T data_; // Container's instance of the data.
public:
// This just wraps an item.
class ContainedItem {
private:
T item_; // Some copy of the data.
public:
explicit ContainedItem (const T &item) : item_(item) { }
const T * getItem () const; // This gets the copy.
};
// Get via ContainedItem.
ContainedItem getData () const { return ContainedItem(data_); }
// Set value directly.
void setData (const T &data) { data_ = data; }
};
// Generic template implementation.
template <typename T>
const T * Container<T>::ContainedItem::getItem () const {
return &item_;
}
=== END ===
Now, my problem is very specific: When T is an arbitrary type I want
Container<T>::ContainedItem::getItem() to return a const T *, just
like it already does. However, when T specifically is a
boost::shared_ptr<X>, I want Container<T>::ContainedItem::getItem() to
return a const X *, not a const T *. For example:
=== BEGIN ===
#include <boost/shared_ptr.hpp>
using boost::shared_ptr;
int main () {
Container<Object> x;
Container<shared_ptr<Object> > y;
x.setData(Object()); // i want this
y.setData(shared_ptr<Object>()); // i want this
x.getData().getItem()->function(); // i want this
y.getData().getItem()->get()->function(); // don't want this!
//y.getData().getItem()->function(); // i want this instead!
}
=== END ===
Basically, as shown above, for shared_ptr<X> template types, I don't
want the extra "get()" in there (boost::shared_ptr<X> does not define
a conversion to X*). Is there some way I can make an explicit
specialization for getItem(), for type T = boost::shared_ptr<X>, and
have it return a const X * (it would return "item_.get()" instead of
"&item_")? I can't figure out the syntax for it, if it's possible.
Is there some other solution instead? It's not that I don't want to
type "get()", it's that I want Container<X> and
Container<shared_ptr<X> > to have getData().getItem() return the same
type for both.
Thanks,
Jason
In this program:
- "Object" is just some example type.
- "Container" holds a single item of some type, but provides access
access to a copy of that object only via a nested class
Container::ContainedItem.
=== BEGIN ===
// An example object with a member function.
class Object {
public:
void function () const { }
};
template <typename T> class Container {
private:
T data_; // Container's instance of the data.
public:
// This just wraps an item.
class ContainedItem {
private:
T item_; // Some copy of the data.
public:
explicit ContainedItem (const T &item) : item_(item) { }
const T * getItem () const; // This gets the copy.
};
// Get via ContainedItem.
ContainedItem getData () const { return ContainedItem(data_); }
// Set value directly.
void setData (const T &data) { data_ = data; }
};
// Generic template implementation.
template <typename T>
const T * Container<T>::ContainedItem::getItem () const {
return &item_;
}
=== END ===
Now, my problem is very specific: When T is an arbitrary type I want
Container<T>::ContainedItem::getItem() to return a const T *, just
like it already does. However, when T specifically is a
boost::shared_ptr<X>, I want Container<T>::ContainedItem::getItem() to
return a const X *, not a const T *. For example:
=== BEGIN ===
#include <boost/shared_ptr.hpp>
using boost::shared_ptr;
int main () {
Container<Object> x;
Container<shared_ptr<Object> > y;
x.setData(Object()); // i want this
y.setData(shared_ptr<Object>()); // i want this
x.getData().getItem()->function(); // i want this
y.getData().getItem()->get()->function(); // don't want this!
//y.getData().getItem()->function(); // i want this instead!
}
=== END ===
Basically, as shown above, for shared_ptr<X> template types, I don't
want the extra "get()" in there (boost::shared_ptr<X> does not define
a conversion to X*). Is there some way I can make an explicit
specialization for getItem(), for type T = boost::shared_ptr<X>, and
have it return a const X * (it would return "item_.get()" instead of
"&item_")? I can't figure out the syntax for it, if it's possible.
Is there some other solution instead? It's not that I don't want to
type "get()", it's that I want Container<X> and
Container<shared_ptr<X> > to have getData().getItem() return the same
type for both.
Thanks,
Jason