How can I `nlohmann::json::get<std::shared_ptr<const T>>`? - c++

I've defined the following serializer stack:
namespace discordpp {
using Snowflake = uint64_t;
}
namespace nlohmann {
template <> struct adl_serializer<discordpp::Snowflake> {
static void to_json(json &j, const discordpp::Snowflake sf) {
j = std::to_string(sf);
}
static void from_json(const json &j, discordpp::Snowflake sf) {
std::istringstream(j.get<std::string>()) >> sf;
}
};
template <typename T> struct adl_serializer<std::shared_ptr<T>> {
static void from_json(json &j, std::shared_ptr<T> &ptr) {
if (j.is_null()) {
ptr == nullptr;
} else {
ptr = std::make_shared<T>(j.get<T>());
}
}
static void to_json(json &j, const std::shared_ptr<T> &ptr) {
if (ptr.get()) {
j = *ptr;
} else {
j = nullptr;
}
}
};
template <typename T> struct adl_serializer<std::shared_ptr<const T>> {
static void from_json(json &j, std::shared_ptr<const T> &ptr) {
if (j.is_null()) {
ptr == nullptr;
} else {
ptr = std::make_shared<const T>(j.get<T>());
}
}
static void to_json(json &j, const std::shared_ptr<const T> &ptr) {
if (ptr.get()) {
j = *ptr;
} else {
j = nullptr;
}
}
};
template <typename T> struct adl_serializer<std::optional<T>> {
static void to_json(json &j, const std::optional<T> &opt) {
if (opt.has_value()) {
j = nullptr;
} else {
j = *opt;
}
}
static void from_json(const json &j, std::optional<T> &opt) {
if (j.is_null()) {
opt = std::nullopt;
} else {
opt = j.get<T>();
}
}
};
}
And I'm poking around with things like so:
class MessageIn : protected util::ObjectIn {
public:
...
opt<sptr<const Snowflake>> guild_id;
...
}
void from_json(const json &j, MessageIn *m) {
...
j["guild_id"].get<Snowflake>();
j["guild_id"].get<const Snowflake>();
j["guild_id"].get<sptr<const Snowflake>>();
m->guild_id = j["guild_id"].get<opt<sptr<const Snowflake>>>();
...
}
My compiler is throwing an error on the j["guild_id"].get<sptr<const Snowflake>>(); line with error: no matching function for call to ‘nlohmann::basic_json<>::get<discordpp::sptr<const long unsigned int> >() const’. Have I missed something?

The std::shared_ptr<const T> synthesizer is not needed.
In the from_json methods of both std::shared_ptr sythesizers the json parameter wasn't static.

Related

dynamically call same named function with different return type

I have a situation here...
I want to design a Factory where I can call a function with same name and no parameters but return different data Types. Based on the SubClassName I need to instantiate the Object.
Need help or lead on any design pattern to follow?
EDIT:
An abstract pseudo code...
class parent{
public:
virtual string getName() = 0;
//some virtual function.. not sure how to design. As the return type is dynamic.
*** getValue(){}
};
class A : public parent{
int x;
public:
virtual string getName(){ return "A";}
virtual int getValue(){retun x;}
};
class B : public parent{
string s;
public:
virtual string getName(){ return "B";}
virtual string getValue(){ return s;}
};
void main(){
string callingClass = "B";
parent * arrayPtrs[2];
arrayPtrs[0] = new A;
arrayPtrs[1] = new B;
for (loop through array, through iterator i){
if(arrayPtrs[i]->getName == callingClass ){
cout<<arrayPtrs[i]->getValue;
}
}
}
In C++ a function can only have one return type at a time, and you cannot change that dynamically.
However - as suggested by #mch - you can use template specializations. Keep in mind though, that this method is not dynamic. Your functions will be generated at compile time.
If I understood your question correctly, maybe this can be of help.
class MyObject1
{
//...
};
class MyObject2
{
//...
};
template<typename T>
struct Factory
{
constexpr static T gen();
};
template<>
struct Factory<MyObject1>
{
constexpr static MyObject1 gen()
{
return MyObject1(/*... whatever parameters you see fit ...*/);
}
};
template<>
struct Factory<MyObject2>
{
constexpr static MyObject2 gen()
{
return MyObject2(/*... whatever parameters you see fit ...*/);
}
};
int main()
{
auto myObj = Factory<MyObject1>::gen();
return 0;
}
Although this method seems fairly useless to me. You could simply call the desired constructor instead of this.
But then again, I'm not sure if this is what you thought of. If I made any mistakes please feel free, to correct me. I'll try to edit my answer best as I can.
EDIT:
To keep the virtual functionality too, the only way I can think of is type erasure: see https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Erasure
The closest I could get to what you've asked for is this:
#include <iostream>
#include <string>
#include <any>
class parent {
public:
// you can use this too but I think type checking is more handy
// see in main function
/* virtual std::string getName() const = 0; */
virtual std::any getValue() const = 0;
};
class A : public parent {
public:
typedef int value_type;
private:
value_type x;
public:
A(value_type x) :
x(x)
{}
/* virtual std::string getName() const override { return "A"; } */
virtual std::any getValue() const override
{ return this->x; }
};
class B : public parent {
public:
typedef std::string value_type;
private:
value_type s;
public:
B(const value_type& s) :
s(s)
{}
/* virtual std::string getName() const override { return "B"; } */
virtual std::any getValue() const override
{ return this->s; }
};
int main(){
using callingClass = A;
parent* arrayPtrs[2];
arrayPtrs[0] = new A(42);
arrayPtrs[1] = new B("my string");
for (unsigned i = 0; i < sizeof(arrayPtrs) / sizeof(parent*); ++i)
{
// Note:
// dynamic cast will return nullptr if $callingClass
// is not a derived class
if (dynamic_cast<callingClass*>(arrayPtrs[i]))
std::cout << std::any_cast<callingClass::value_type>(arrayPtrs[i]->getValue()) << std::endl;
}
return 0;
}
I hope this one helps.
Note, that I used dynamic_cast to check the correct type. If you know a better solution, you can use that, too. But under these circumstances I couldn't think of any better.
EDIT2:
#include <iostream>
#include <string>
#include <tuple>
class some
{
using id = size_t;
template<typename T>
struct type { static void id() { } };
template<typename T>
static id type_id() { return reinterpret_cast<id>(&type<T>::id); }
template<typename T>
using decay = typename std::decay<T>::type;
template<typename T>
using none = typename std::enable_if<!std::is_same<some, T>::value>::type;
struct base
{
virtual ~base() { }
virtual bool is(id) const = 0;
virtual base *copy() const = 0;
} *p = nullptr;
template<typename T>
struct data : base, std::tuple<T>
{
using std::tuple<T>::tuple;
T &get() & { return std::get<0>(*this); }
T const &get() const& { return std::get<0>(*this); }
bool is(id i) const override { return i == type_id<T>(); }
base *copy() const override { return new data{get()}; }
};
template<typename T>
T &stat() { return static_cast<data<T>&>(*p).get(); }
template<typename T>
T const &stat() const { return static_cast<data<T> const&>(*p).get(); }
template<typename T>
T &dyn() { return dynamic_cast<data<T>&>(*p).get(); }
template<typename T>
T const &dyn() const { return dynamic_cast<data<T> const&>(*p).get(); }
public:
some() { }
~some() { delete p; }
some(some &&s) : p{s.p} { s.p = nullptr; }
some(some const &s) : p{s.p->copy()} { }
template<typename T, typename U = decay<T>, typename = none<U>>
some(T &&x) : p{new data<U>{std::forward<T>(x)}} { }
some &operator=(some s) { swap(*this, s); return *this; }
friend void swap(some &s, some &r) { std::swap(s.p, r.p); }
void clear() { delete p; p = nullptr; }
bool empty() const { return p; }
template<typename T>
bool is() const { return p ? p->is(type_id<T>()) : false; }
template<typename T> T &&_() && { return std::move(stat<T>()); }
template<typename T> T &_() & { return stat<T>(); }
template<typename T> T const &_() const& { return stat<T>(); }
template<typename T> T &&cast() && { return std::move(dyn<T>()); }
template<typename T> T &cast() & { return dyn<T>(); }
template<typename T> T const &cast() const& { return dyn<T>(); }
template<typename T> operator T &&() && { return std::move(_<T>()); }
template<typename T> operator T &() & { return _<T>(); }
template<typename T> operator T const&() const& { return _<T>(); }
};
using any = some;
class parent {
public:
// you can use this too but I think type checking is more handy
/* virtual std::string getName() const = 0; */
virtual any getValue() const = 0;
};
class A : public parent {
public:
typedef int value_type;
private:
value_type x;
public:
A(value_type x) :
x(x)
{}
/* virtual std::string getName() const override { return "A"; } */
virtual any getValue() const override
{ return this->x; }
};
class B : public parent {
public:
typedef std::string value_type;
private:
value_type s;
public:
B(const value_type& s) :
s(s)
{}
/* virtual std::string getName() const override { return "B"; } */
virtual any getValue() const override
{ return this->s; }
};
int main(){
using callingClass = A;
parent* arrayPtrs[2];
arrayPtrs[0] = new A(42);
arrayPtrs[1] = new B("my string");
for (unsigned i = 0; i < sizeof(arrayPtrs) / sizeof(parent*); ++i)
{
// Note:
// dynamic cast will return nullptr if $callingClass
// is not a derived class
if (dynamic_cast<callingClass*>(arrayPtrs[i]))
std::cout << arrayPtrs[i]->getValue()._<callingClass::value_type>() << std::endl;
}
return 0;
}
This snipped is in case you cannot use C++17 features, and is based on:
any class

passing std::type_info for identifying void *

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.

How to use template in the class itself in c++?

RequestS want to use ReportUrlThread's function(send) .ReportUrlThread is a template class.
It look like below the code is that "request->process(reportUrl->send);",
how can I achieve it?
The codes below can't be through compilation.
int main()
{
typedef Threadpool<RequestS> ThreadpoolDealFromBS2;
ThreadpoolDealFromBS2 threadpool;
ReportUrlReq* req = new ReportUrlReq();
threadpool.appendReportHiUrl(req);
}
class RequestS {
public:
RequestS()
{
}
virtual ~RequestS()
{
}
virtual void process(void (*send)(bool &exp))
{
log(Info, "RequestS...fun");
}
};
class ReportUrlReq:public RequestS {
public:
ReportUrlReq();
~ReportUrlReq();
virtual void process(void (*send)(bool &exp))
{
log(Info, "ReportUrlReq...fun");
}
};
template< typename T >
class ReportUrlThread {
public:
ReportUrlThread(uint32_t id)
{
}
virtual ~ReportUrlThread()
{
}
void send(bool &exp)
{
}
Threadpool< T >* threadpool;
};
template< typename T >
class Threadpool
{
public:
Threadpool( std::vector<ReportUrlThread<T>*>& reportUrl);
~Threadpool();
bool appendReportHiUrl( T* request );
private:
static void* reportWorker( void* arg );
void reportRun(ReportUrlThread<T> *reportUrl);
pthread_t* m_ReportUrlThreads;
};
template< typename T >
Threadpool< T >::Threadpool( std::vector<ReportUrlThread<T>*>& reportUrl)
{
m_ReportUrlThreads = new pthread_t[reportUrlThreadNum];
for (int i = 0; i < 10; ++i)
{
ReportUrlThread<T> * reportUrlThread = reportUrl[i];
reportUrlThread->threadpool = this;
if( pthread_create( m_ReportUrlThreads + i, NULL, reportWorker, reportUrlThread ) != 0 )
{
delete [] m_ReportUrlThreads;
throw std::exception();
}
if( pthread_detach( m_ReportUrlThreads[i] ) )
{
delete [] m_ReportUrlThreads;
throw std::exception();
}
}
}
template< typename T >
void* Threadpool< T >::reportWorker( void* arg )
{
ReportUrlThread<T>* reportUrl = (ReportUrlThread<T>*)arg;
Threadpool* pool = reportUrl->threadpool;
pool->reportRun(reportUrl);
return pool;
}
template< typename T >
void Threadpool< T >::reportRun(ReportUrlThread<T> *reportUrl)
{
while ( ! m_ReportStop )
{
m_ReportQueuestat.wait();
m_ReportQueuelocker.lock();
if ( m_ReportWorkqueue.empty() )
{
m_ReportQueuelocker.unlock();
continue;
}
T* request = m_ReportWorkqueue.front();
m_ReportWorkqueue.pop_front();
reportDealNum++;
m_ReportWorkqueueSize = m_ReportWorkqueue.size();
request->process(reportUrl->send);
}
}
The actual error is, that you're passing the memberfunction reportUrl->send to request->process expecting an ordinary function. But a member function needs an instance of its class! If send depends on members of ReportUrlThread, you might want to pass an instance of ReportUrlThread (or a derived class implementing send):
virtual void process(ReportUrlThread<RequestS> *RepUrlThReqS) {
bool exp;
RepUrlThReqS->send(exp);
// ...
}
If not, you might want to use a static function:
static void send(bool &exp) {
// ...
}
You might even want to use a lambda function (which is quite a bit hacky here):
class RequestS {
public:
virtual void process(void(*send)(bool &exp, void* instance), void *instance) {
bool exp;
send(exp, instance);
}
};
template< typename T >
class ReportUrlThread {
public:
void send(bool &exp) { }
};
int main() {
ReportUrlThread<RequestS> *reportUrl = new ReportUrlThread<RequestS>;
RequestS *request = new RequestS;
request->process(
[](bool &exp, void* reportUrlA) {
((ReportUrlThread<RequestS> *)reportUrlA)->send(exp);
}, reportUrl);
}
And many more possibilities...
It's up to you to decide, which is the best solution in your case.

How to get argument type from type of boost::bind(c++11 NOT available)

I am wring a generic class to extract something of type SrcT by a string key, convert it to type TargetT and then return. Like:
class Foo
{
public:
bool get(const char* key, std::string& str)
{
if (std::string(key) == "found")
{
str = "stringA";
return true;
}
return false;
}
bool get(const char* key, int& a)
{
a = 100;
return true;
}
};
class Bar
{
public:
template <typename Converter>
typename Converter::result_type extract(const char* key, Converter converter)
{
typedef typename Converter::first_argument_type SrcT; // <- HERE IS THE ERROR
typedef typename Converter::result_type TargetT;
SrcT temp;
if (_foo.get(key, temp))
{
TargetT target = converter(temp);
return target;
}
else
{
throw std::runtime_exception("ah");
}
}
Foo _foo;
};
struct Converters
{
static int toInt(const std::string& str) { return str.size(); }
static float toFloat(int a) { return 100.0 + a; }
};
BOOST_AUTO_TEST_CASE(Nothing)
{
Bar bar;
const int saveHere = bar.extract("found", boost::bind(&Converters::toInt, _1));
BOOST_CHECK_EQUAL(saveHere, 7); // 7=sizeof("stringA")
}
TargetT was deduced from Converter type, but no clue about SrcT.
Any help is appreciated.
UPDATE
After checking boost/bind.hpp and boost/bind/bind_template.hpp, looks like no such thing was exposed.
Try with:
typedef typename boost::function_traits<Converter>::arg1_type SrcT;

Cannot assign int to member int of returned class

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;