What is the best way to deal with the fact that some types require members / methods to be accessed with the . operator whilst others with the -> operator.
Is it best to write the code for the . operator and have the caller wrap the type as show in the code sample below.
Coming from a C# background I am not use to having this particular issue.
#include <iostream>
#include <string>
#include <vector>
#include <memory>
template<class T>
class container{
public:
void add(T element){
elements_.push_back(std::move(element));
}
void process(){
for(auto& a: elements_){
a.print();
}
}
private:
std::vector<T> elements_;
};
class printable{
public:
void print(){
std::cout << "Print\n";
}
};
template<class T>
class printable_forwarder{
public:
printable_forwarder(T element): element_{std::move(element)}{
}
void print(){
element_->print();
}
private:
T element_;
};
int main()
{
container<printable> c1;
c1.add(printable{});
c1.process();
container<printable_forwarder<std::shared_ptr<printable>>> c2;
std::shared_ptr<printable> sp{std::make_shared<printable>()};
c2.add(printable_forwarder<decltype(sp)>{sp});
c2.process();
}
Does this appear better?
#include <iostream>
#include <string>
#include <memory>
#include <type_traits>
#include <vector>
template<typename T>
class dereference
{
public:
inline static T& get(T& value){
return value;
}
};
template<typename T>
class dereference<T*>
{
public:
inline static typename std::add_lvalue_reference<typename std::remove_pointer<T>::type>::type get(T* value){
return *value;
}
};
template<typename T>
class dereference<std::shared_ptr<T>>
{
public:
inline static T& get(std::shared_ptr<T> value){
return *value.get();
}
};
template<class T>
class container{
public:
void add(T const& v){
items_.push_back(v);
}
void print_all(){
for(auto& a: items_){
dereference<T>::get(a).print();
}
}
private:
std::vector<T> items_;
};
struct printable{
void print(){
std::cout << "Printing\n";
}
};
int main()
{
container<printable> c1;
c1.add(printable{});
c1.print_all();
container<std::shared_ptr<printable>> c2;
c2.add( std::shared_ptr<printable>(new printable{}));
c2.print_all();
}