Here is the deal:
I have a templated class C
template<class T>
class C;
that has a member that is basically a pointer to a reinterpretation of T called P (don't worry about P)
P* reint;
what I want to do is a method that receives a T and copies it into reint
void foo (T& param) {
new (reint) (param);
}
problem is the compiler is giving out warnings that reint is not a T that I want to get rid of. My first idea was to reinterpret reint into a T:
void foo (T& param) {
new (reinterpret_cast<T&>(*reint)) T(param);
}
but the compiler started giving me an error saying
invalid conversion from const void* to void*
So i looked it up and new is defined as such:
void* operator new (std::size_t size, void* ptr) throw();
So for some reason my casting is turning reint into a const void*.
New idea: cast reint to a T and call the copy constructor. Problem: no clue how to call the copy constructor from an unknown class.
(maybe
reinterpret_cast<T>(*reint).T(param);
?)
Could you help me please?
Maybe you want something like:
#include <stdexcept>
struct Data
{
const std::string value;
Data(const std::string& value)
: value(value)
{}
Data(const Data& other) = default;
Data& operator = (const Data& other) = delete;
};
template <typename T>
class Holder
{
public:
Holder() = default;
Holder(const T& data) {
assign(data);
}
~Holder() {
release();
}
void assign(const T& data) {
release();
new (m_data) T(data);
m_valid = true;
}
void release() {
if(m_valid) {
reinterpret_cast<T*>(m_data)->~T();
m_valid = false;
}
}
const T& get() const {
if( ! m_valid) throw std::runtime_error("Invalid");
return *reinterpret_cast<const T*>(m_data);
}
private:
bool m_valid = false;
char m_data[sizeof(T)];
};
#include <iostream>
int main() {
Holder<Data> holder;
holder.assign(Data("Hello"));
const Data& data = holder.get();
std::cout << data.value << '\n';
}
You're going the wrong way, you want somethng more like:
reint = reinterpret_cast<P*>(param);
The solution was to make a struct to return the reinterpreted P for both const and unconst
template <class T> struct Temp {
T* switch (P* r) { return reinterpret_cast<T*>(r); }
}
template <class T> struct Temp <const T> {
T* switch (P* r) { return reinterpret_cast<T*>(r); }
}
then use the struct to remove const from reint
new (Temp::switch(reint)) T(param);
Related
I have to pass around the void * for supporting types that can't be known at compile time, but I also don't want to go totally insane and left everything on myself so I think to use type_info for type_Checking but since type_info doesn't support copy operation I am getting compiler errors when passing them around
#include <bits/stdc++.h>
struct PropertyClassInterface {
virtual const char * name() = 0;
virtual void set(const char * property_name,std::pair<const void *,std::type_info> new_val) = 0;
virtual std::pair<std::shared_ptr<void>,std::type_info> get(const char * property_name) = 0;
template< typename Type>
static std::pair<std::shared_ptr<void>,std::type_info> get_type_pair(const Type& Value) {
std::shared_ptr<void> t = std::make_shared<Type>();
*static_cast<Type *>(t.get()) = Value;
*return std::make_pair(t,typeid(Type));* // error
}
};
struct PropertyManager {
using base_pointer = std::shared_ptr<PropertyClassInterface>;
void add_object(base_pointer new_member) {
objects.push_back(new_member);
}
template<typename Type>
void set(const char * object_name,const char * property_name,const Type& new_val) {
find_object_orThrow(object_name)->set(property_name,std::make_pair(static_cast<const void *>(&new_val),typeid(new_val)));
}
template<typename Type>
Type get(const char * object_name, const char * property_name) {
auto a = find_object_orThrow(object_name)->get(property_name);
if (typeid(Type).hash_code() != a.second.hash_code())
throw std::runtime_error{"get(): mismatched type"};
return a.first;
}
public:
std::vector<base_pointer> objects;
base_pointer find_object_orThrow(const char * obj_name){
for(auto& o : objects) {
if (!strcmpi(o->name(),obj_name)) {
return o;
}
}
throw std::runtime_error{std::string("no object named \"") + obj_name + "\" found"};
}
};
struct testClass : PropertyClassInterface {
void set(const char * property_name,std::pair<const void *,std::type_info> new_val) {
auto checkTypeInfo = [&new_val](const std::type_info& expected) {
if (new_val.second.hash_code() != expected.hash_code())
throw std::runtime_error{"set(): wrong type"};
};
if (!strcmpi(property_name,"my_number")) {
checkTypeInfo(typeid(decltype(my_number)));
my_number = *static_cast<const decltype(my_number) *>(new_val.first);
}
};
std::pair<std::shared_ptr<void>,std::type_info> get(const char * property_name) {
if (!strcmpi(property_name,"my_number")) {
PropertyClassInterface::get_type_pair(my_number);
}
}
private:
int my_number;
};
int main() {
};
so do I have to use dynamic memory for storing type_info as well
I am limited to c++11 and I know about not using bits headers and am only using for testing
What you want to do is implement an any, or use boost any.
An any isn't hard to write.
namespace details {
struct any_concept;
using pimpl=std::unique_ptr<any_concept>;
struct any_concept {
virtual ~any_concept() {}
virtua pimpl clone() const = 0;
virtual std::type_info const& type() const = 0;
private:
virtual void* unsafe_get() = 0;
virtual void const* unsafe_get() const = 0;
public:
template<class T>
T* get() {
if (typeid(T) != type()) return nullptr;
return static_cast<T*>(unsafe_get());
}
template<class T>
T const* get() const {
if (typeid(T) != type()) return nullptr;
return static_cast<T const*>(unsafe_get());
}
};
template<class T>
struct any_model:any_concept {
T t;
virtual ~any_model() = default;
virtual pimpl clone() const final override {
return pimpl( new any_model(t) );
}
virtual std::type_info const& type() const final override {
return typeid(T);
}
template<class U>
any_model(U&& u):t(std::forward<U>(u)){}
private:
virtual void* unsafe_get() final override { return std::addressof(t); }
virtual void const* unsafe_get() const final override { return std::addressof(t); }
};
}
struct any {
template<class T, typename std::enable_if<!std::is_same<any, typename std::decay<T>::type>::value, bool> =true>
any( T&& t ):
pImpl( new details::any_model<typename std::decay<T>::type>( std::forward<T>(t) ) )
{}
template<class T>
T* get() {
if (!pImpl) return nullptr;
return pImpl->get<T>();
}
template<class T>
T const* get() const {
if (!pImpl) return nullptr;
return const_cast<details::any_concept const&>(*pImpl).get<T>();
}
template<class T>
bool contains()const { return get<T>(); }
explicit operator bool() const {
return (bool)pImpl;
}
any()=default;
any(any&&)=default;
any& operator=(any&&)=default;
~any()=default;
any(any const& o):
pImpl( o.pImpl?o.pImpl->clone():pimpl{} )
{}
any& operator=(any const& o) {
any tmp(o);
std::swap(*this, tmp);
return *this;
}
private:
details::pimpl pImpl;
};
there; a really simple any implementation. Written on a phone, so probably contains typos.
It supports value semantics, but store anything (that can be copied and destroyed). If you know what it stores, you can .get<T>() it. You can ask it if it contains<T>() as well.
This is known as a vocabulary type. It is basically your void* and type info bundled in a way that makes misuse more difficult.
This question is just for improvement purpose. There is a function below:
void Func_A(u8* arg) {
bool local_arg=false;
if(!arg) {
//allocate memory for arg
local_arg=true;
}
//process arg
I am calling this function from multiple places with NULL and non NULL argument.
I just want to ask whther there is a better way of handling such this without local_arg or not.
You can sometimes use...
u8* p = arg ? arg : new u8(...);
...do things with *p...
if (!arg) delete p;
A little fancier, you can write a smart pointer with runtime-configurable ownership:
template <typename T>
class Uncertain_Ownership_Ptr
{
public:
enum Ownership { Own_It, Dont_Own_It };
Uncertain_Ownership_Ptr(T* p, Ownership own) : p_(p), own_(own) { }
Uncertain_Ownership_Ptr(const Uncertain_Ownership_Ptr&) = delete;
void operator=(const Uncertain_Ownership_Ptr&) = delete;
~Uncertain_Ownership_Ptr() { if (own_ == Own_It) delete p_; }
T& operator*() { return *p_; }
const T& operator*() const { return *p_; }
T* operator->() { return p_; }
const T* operator->() const { return p_; }
private:
T* p_;
Ownership own_;
};
...then...
void Func_A(u8* arg)
{
Uncertain_Ownership_Ptr p(arg ? arg : new u8(...),
arg ? Uncertain_Ownership_Ptr::Dont_Own_It : Uncertain_Ownership_Ptr::Own_It);
// use *p ...
}
I am trying to make a basic any type implementation in C++ (object), yet it always prints CCCCCCCC if I want to get the value from any type, and it is confusing me why (although I do know void*s are dangerous):
#include <typeinfo>
struct object
{
private:
template < typename T > struct _base
{
typedef T _ptr_type;
_ptr_type* _ptr_val()
{
return _ptr;
}
_base(_ptr_type value) : _ptr(&value){}
_base() : _ptr(nullptr){}
_ptr_type* _ptr;
};
struct _holder : _base<void*>
{
template < typename Ty > void cast(const _base<Ty>* p_base)
{
_ptr->~_ptr_type();
_ptr_type _n_type = (_ptr_type)p_base->_ptr, *_n_ptr = &_n_type;
std::swap<_ptr_type*>(_ptr, _n_ptr);
}
_holder(){}
};
public:
_holder* _h_ptr;
object() : _h_ptr(new _holder){}
template < typename T > object(const T& value) : _h_ptr(new _holder)
{
_base<T> _t_base(value);
_h_ptr->cast(&_t_base);
}
template < typename T > void operator=(const T& value)
{
_base<T> _t_base(value);
_h_ptr->cast(&_t_base);
}
const void* operator()() const
{
return *_h_ptr->_ptr_val();
}
};
#include <iostream>
int main()
{
object MyObject = 'c';
std::cout << MyObject();
getchar();
}
Perhaps my implementation of the object class will help you. It is similar to boost::any, but has a few more features (operator== and operator!=)
class object
{
private:
class dummy
{
public:
dummy()
{
}
virtual ~dummy()
{
}
virtual const std::type_info &type() const = 0;
virtual dummy *duplicate() const = 0;
virtual bool eq(object) = 0;
};
template < typename _Ty > class data : public dummy
{
public:
data()
{
}
data(const _Ty &_Value)
: __data(_Value)
{
}
~data()
{
}
const std::type_info &type() const
{
return typeid(_Ty);
}
data *duplicate() const
{
return new data<_Ty>(__data);
}
bool eq(object _Obj)
{
return _Obj.cast<_Ty>() == __data;
}
_Ty __data;
};
dummy *d;
public:
object()
{
}
template < typename _Ty > object(const _Ty &_Value)
: d(new data<_Ty>(_Value))
{
}
object(const object &_Obj)
: d(_Obj.d->duplicate())
{
}
~object()
{
if (!empty())
{
delete d;
}
}
const std::type_info &type() const
{
return (empty() ? typeid(void) : d->type());
}
object &operator=(object &_Rhs)
{
if (&_Rhs != this)
{
d = _Rhs.d->duplicate();
}
return *this;
}
object &swap(object &_Rhs)
{
std::swap(*this, _Rhs);
return *this;
}
template < typename _Ty > object &operator=(const _Ty &_Value)
{
d = new data<_Ty>(_Value);
return *this;
}
template < typename _Ty > _Ty cast() const
{
if (type() == typeid(_Ty))
{
return static_cast<data<_Ty> *>(d)->__data;
}
throw std::exception("Invalid cast type");
}
bool operator==(const object &_Rhs) const
{
return (type() == _Rhs.d->type() ? d->eq(_Rhs) : false);
}
template < typename _Ty > bool operator==(_Ty _Value) const
{
return (type() == typeid(_Ty) ? cast<_Ty>() == _Value : false);
}
bool operator!=(const object &_Rhs) const
{
return !(*this == _Rhs);
}
template < typename _Ty > bool operator!=(_Ty _Value) const
{
return !(*this == _Value);
}
bool empty() const
{
return !d;
}
};
I am afraid just like boost::any, there is no getter function, but a cast function. It can be used like this
int main()
{
object o = 5;
object o = (std::string)"Hello\n"; // doesn't like arrays, must be wrapped in a class
std::cout << o.cast<std::string>().c_str();
}
I'm sorry, but your implementation makes absolutely no sense whatsoever. It seems to be based on a completely flawed understanding of memory and the C++ object model, as well as templates. I think in your example program execution, every line of cast invokes undefined behavior, to the point where it's impossible to say what actually happens.
Throw it away and start again from scratch.
template < typename T > struct _base
{
typedef T _ptr_type;
_base(_ptr_type value) : _ptr(&value){}
_ptr_type* _ptr;
};
Well, the constructor recieves a _ptr_type by value, which means a temporary copy on the stack. _ptr(&value) makes the internal pointer point at this temporary. Then the constructor returns, and the temporary is destroyed, making this entire class broken. I'm not sure what the point of this class is yet, so I cannot make suggestions as to how to fix it.
struct _holder : _base<void*>
{
template < typename Ty > void cast(const _base<Ty>* p_base)
{
_ptr->~_ptr_type();
_ptr_type _n_type = (_ptr_type)p_base->_ptr, *_n_ptr = &_n_type;
std::swap<_ptr_type*>(_ptr, _n_ptr);
}
};
I don't know what this is for either, but the first step of your cast is to destroy the data. That's... probably a bad idea. Then you point _n_type at the data of p_base, and then make this->_ptr point at the temporary _n_type pointer which is on the stack, which means that when the function ends, this->_ptr points at invalid data again.
I have no idea how you thought this was supposed to work, so here's a rundown of the normal interface for this sort of thing:
struct object
{
private:
//base is a non-template, pure virtual interface
//used to store and access all internal data
//without knowing the actual type
struct _interface //not a template
{
virtual ~_interface () =0 {};
//clone allows us to copy without knowing the type
virtual std::unique_ptr<_interface> clone() const = 0 {}
};
//this actually stores the data
//it may be given other members, but using these
//members requires `object` to know the type
template< typename T>
struct data: _interface
{
//data() : _data() {} //default constructor - not used
//data(const data& rhs) : _data(rhs._data) {} //copy constructor - not used
//data(data&& rhs) : _data(std::move(rhs._data)) {} //move constructor - not used
data(const T& rhs) : _data(rhs) {} //value by copy
data(T&& rhs) : _data(std::move(rhs)) {} //value by move
template< typename... Us>
data(Us&&...vs) : _data(std::forward<Us>(vs)...) {} //emplace constructor
std::unique_ptr<_interface> clone() const //virtual cloning mechanism
{return std::unique_ptr<data>(new T(_data));}
T _data;
};
std::unique_ptr<_interface> _ptr;
public:
object() //default constructor
: _ptr() {}
object(const object&& rhs) //copy constructor
: _ptr(rhs ? rhs._ptr->clone() : {}) {}
object(object&& rhs) //move constructor
: _ptr(std::move(rhs._ptr)) {}
template < typename U> object(const U& _Value) //value by copy
: _ptr(new data<U>(_Value)) {}
template < typename U> object(U&& _Value) //value by move
: _ptr(new data<U>(std::move(_Value)) {}
object& operator=(const object& rhs) //copy assignment
{_ptr = rhs ? rhs._ptr->clone() : {}; return *this;}
object& operator=(object&& rhs) //move assignment
{_ptr = std::move(rhs._ptr); return *this;}
//*_ptr gives you a _interface&
//dynamic_cast<data<T>&> gives you a _data<T>& or throws a std::bad_cast
//._data gives the actual value
template< typename T> T& get()
{return dynamic_cast<data<T>&>(*_ptr)._data;}
template< typename T> const T& get() const
{return dynamic_cast<const data<T>&>(*_ptr)._data;}
explicit operator bool() const {return _ptr;} //object o; if (o) then ....
};
This only handles bare basics. Everything else is left up to you.
Not 100% sure whether my question is worded correctly as I don't fully understand my problem.
For my course I need to create my own smart pointer to clean up after itself.
Here's my code so far:
Header:
class Test
{
public:
Test()
{
m_iTest1 = 4;
m_iTest2 = 3;
m_iTest3 = 2;
m_iTest4 = 1;
}
Test (int a, int b, int c, int d)
{
m_iTest1 = a;
m_iTest2 = b;
m_iTest3 = c;
m_iTest4 = d;
}
Test(const Test& a_oTest)
{
m_iTest1 = a_oTest.m_iTest1;
m_iTest2 = a_oTest.m_iTest2;
m_iTest3 = a_oTest.m_iTest3;
m_iTest4 = a_oTest.m_iTest4;
}
~Test(){;}
int m_iTest1;
int m_iTest2;
int m_iTest3;
int m_iTest4;
};
template<class T>
class SmartData
{
public:
template<class T> friend class SmartPointer;
SmartData();
SmartData(const T& a_oData);
~SmartData();
T operator * () const;
unsigned int GetCount(){return m_uiCount;}
protected:
void IncrementCount(){++m_uiCount;}
void DecrementCount();
void DeleteThis();
unsigned int m_uiCount;
T* m_poData;
};
template<class T>
class SmartPointer
{
public:
SmartPointer();
SmartPointer(SmartData<T>& a_oSmartData);
SmartPointer(const SmartPointer& a_oSmartPointer);
~SmartPointer();
SmartPointer<T>& operator = (const SmartPointer<T>& a_oSmartPointer);
T operator *() const;
SmartData<T>* operator ->() const;
unsigned int GetCount() const;
private:
SmartData<T>* m_poSmartData;
};
#include "smartpointer.inl"
Inline file:
template<class T>
SmartData<T>::SmartData()
{
m_uiCount = 0;
m_poData = new T();
}
template<class T>
SmartData<T>::SmartData(const T& a_oData)
{
m_uiCount = 0;
m_poData = new T(a_oData);
}
template<class T>
SmartData<T>::~SmartData()
{
if (m_poData)
{
delete m_poData;
}
}
template<class T>
T SmartData<T>::operator * () const
{
return *m_poData;
}
template<class T>
void SmartData<T>::DecrementCount()
{
if (m_uiCount - 1 == 0 || m_uiCount == 0)
{
DeleteThis();
return;
}
--m_uiCount;
}
template<class T>
void SmartData<T>::DeleteThis()
{
if (m_poData)
{
delete m_poData;
m_poData = 0;
}
}
template<class T>
SmartPointer<T>::SmartPointer()
{
m_poSmartData = new SmartData<T>();
m_poSmartData->IncrementCount();
}
template<class T>
SmartPointer<T>::SmartPointer(SmartData<T>& a_oSmartData)
{
m_poSmartData = &a_oSmartData;
m_poSmartData->IncrementCount();
}
template<class T>
SmartPointer<T>::SmartPointer(const SmartPointer& a_oSmartPointer)
{
m_poSmartData = a_oSmartPointer.a_oSmartData;
m_poSmartData->IncrementCount();
}
template<class T>
SmartPointer<T>::~SmartPointer()
{
m_poSmartData->DecrementCount();
m_poSmartData = 0;
}
template<class T>
SmartPointer<T>& SmartPointer<T>::operator = (const SmartPointer<T>& a_oSmartPointer)
{
m_poSmartData = a_oSmartPointer.m_poSmartData;
m_poSmartData->IncrementCount();
}
template<class T>
T SmartPointer<T>::operator *() const
{
return *m_poSmartData->m_poData;
}
template<class T>
SmartData<T>* SmartPointer<T>::operator ->() const
{
return m_poSmartData;
}
template<class T>
unsigned int SmartPointer<T>::GetCount() const
{
return m_poSmartData->m_uiCount;
}
main.cpp
void SomeFunction1(SmartData<Test>& a_SmartData)
{
SmartPointer<Test> oSmartPointer2(a_SmartData);
}
void main()
{
SmartData<int> oSmartData1(5);
if (1)
{
SmartPointer<int> oSmartPointer1(oSmartData1);
int iTemp1 = oSmartPointer1->GetCount();
int iTemp2 = *oSmartPointer1;
int iTemp3 = *oSmartData1;
}
if (1)
{
SmartData<int> oSmartData2(5);
}
SmartData<Test> oSmartData3;
(*oSmartData3).m_iTest1 = 5; //Does not work
if (1)
{
SmartData<Test> oSmartData4(oSmartData3);
SomeFunction1(oSmartData3);
//oSmartData4 still exits
}
}
Everything works fine, the data is cleaned up after itself and I get no leaks... except for one line:
(*oSmartData3).m_iTest1 = 5;
I'm compiling with visual studio, and when I place the "." after "(*oSmartData3)"... "m_iTest1" comes up correctly. Except I get an error:
error C2106: '=' : left operand must be l-value
I'm not sure why this doesn't work or what to change so it does work.
Look closer at the declaration of operator*() in SmartData:
T operator * () const;
This means that this operator is returning an object of type T, which is a copy of m_poSmartData->m_poData. It is a temporary object in this context:
(*oSmartData3).m_iTest1 = 5; //Does not work
Of course, you cannot assign a value to a temporary object, because it is not an l-value. Read more about what l-values and r-values are here: http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7a.doc%2Flanguage%2Fref%2Fclrc05lvalue.htm
I would suggest that you return a reference to m_poSmartData->m_poData
in operator*() (if I'm understanding correctly what you are trying to do).
Your T operator *() const is returning a temporary object (i.e. a copy), which is not an l-value (cannot be assigned to). Return a reference instead:
T& operator *() const;
Does this work:
oSmartData3.m_iTest1 = 5;
I need to create a generic object carrier class. I came up with something simple like
template<typename T>
class ObjectCarrier
{
public:
const T& item() const
{
return item_;
}
void setItem(T& item)
{
item_ = item;
}
private:
T item_;
};
This works well when T has got a default constructor (parameterless). Things gets complicated when T has parameterized constructors. So I rewrote the class like
template<typename T>
class ObjectCarrier
{
public:
const T& item() const
{
return *item_;
}
void setItem(T& item)
{
item_ = new T ( item );
}
private:
T* item_;
};
Changed the item_ variable to T* and created a new instance using the copy constructor of T. Again this worked well until T is a pointer type. I mean ObjectCarrier<Foo*> won't work.
I am wondering how can I design this class so that it works for almost all kind of types. I think I may need to create a traits type specialized for pointers. But unfortunately, I am not able to make that work.
Any help would be great.
The above approaches are way way too complicated. Keep it simple, and just solve the constructor arg problem by using template constructors. Don't use pointers, they will create object lifetime and copying headaches.
Here's an implementation I use a lot. The template constructors will forward arguments for things directly on to the nested object which is convenient. The operator T& values let you pass carrier<T> to functions that take a type T, without expensive copying. You can wrap objects that take up to two arguments with this code.
/* A wrapper of type T */
template <typename T>
struct carrier {
carrier() {}
template <typename A1> carrier(const A1& a1) : value(a1) {}
template <typename A1, typename A2> carrier(const A1& a1, const A2& a2) : value(a1, a2) {}
operator T&() { return value; }
operator const T&() const { return value; }
T value;
};
You can use it like this:
const carrier<point> p1(10,10); // make p1 const to stop people changing it
showPoint(p1); // calls a function that expects a point,
showPoint(p1.value); // access the point directly
You can use template specialization for the T* type and rewrite the methods to suite pointers. You can do something like:
template<typename T>
class ObjectCarrier<T*>
{
public:
const T* item() const
{
return item_;
}
void setItem(T* item)
{
item_ = item;
}
private:
T* item_;
};
There is a design patern that is possibly relevant to this - Memento.
A bit off topic, but bear in mind that as soon as you start newing objects up inside your class, you'll need a way to manage the memory. I'd suggest using an std::auto_ptr at the least. You'll also need to provide a copy constructor and an assignment operator, when using std::auto_ptr.
It might be possible to hold the object by value and still defer its construction with the use of placement new and something like the following:
#include <iostream>
#include <cassert>
template <class T>
class ObjectCarrier
{
public:
ObjectCarrier(): ref(0) {}
ObjectCarrier(const ObjectCarrier& other): ref(0)
{
set_data(other.ref);
}
~ObjectCarrier()
{
clear();
}
const ObjectCarrier& operator = (const ObjectCarrier& other)
{
if (other.empty())
clear();
else
set_data(other.ref);
return *this;
}
void set(const T& value)
{
set_value(value);
}
const T& get() const
{
assert(!empty() && "No object being carried");
return *ref;
}
bool empty() const
{
return ref == 0;
}
void clear()
{
if (!empty()) {
ref->~T();
ref = 0;
}
}
private:
char data[sizeof(T)];
T* ref;
void set_value(const T& value)
{
if (!empty()) {
*ref = value;
}
else {
ref = new (data) T(value);
}
}
void set_data(const T* value)
{
if (value) {
set_value(*value);
}
}
};
int main()
{
ObjectCarrier<int> i;
ObjectCarrier<int> j(i);
i = j;
i.set(10);
std::cout << i.get() << '\n';
j = i;
i.set(20);
std::cout << i.get() << ' ' << j.get() << ' ' << ObjectCarrier<int>(i).get() << '\n';
}
However, I would somewhat question the usefulness of this class. Perhaps the only purpose it could have, would be to act as Boost.Optional.
But if you don't want the class to be able to not hold a value, just give it a parametrized constructor:
template<typename T>
class ObjectCarrier
{
public:
ObjectCarrier(const T& value = T()):
item_(value)
{
}
const T& item() const
{
return item_;
}
void setItem(T& item)
{
item_ = item;
}
private:
T item_;
};
(It's just that this class seems rather useless, unless perhaps as a facade for code that expects variables to have item and setItem methods, rather than, say, an assignment operator.)
boost::optional does something very similar to this (also boost::any, but nevermind).
You can check out how its implemented at: http://cplusplus.co.il/2009/12/04/boost-optional-and-its-internals/ and don't worry - it's pretty straightforward.