Boost: разыменовать аргумент шаблона, если это указатель - PullRequest
7 голосов
/ 15 июня 2011

Что можно использовать для разыменования аргумента шаблона, если он является указателем (или умным указателем), или оставить его как есть, если это не так?

template<class T> void subf(const T& item)
{
    item.foo();
}

template<class T> void f(const T& item)
{
    subf(magic_dereference_function(item));
}

Все, что в Boost - это опция.

Ответы [ 4 ]

12 голосов
/ 15 июня 2011
template <typename T>
T& maybe_deref(T& x) { return x; }

template <typename T>
T& maybe_deref(T* x) { return *x; }

Вам придется добавлять перегрузки для интеллектуальных указателей по отдельности.Нет способа определить, является ли класс «умным указателем».Вы можете обнаружить присутствие operator->, но это не значит, что это умный указатель.

3 голосов
/ 15 июня 2011

Как насчет перегрузки?

template<class T>
T& deref(T& t){
  return t;
}

template<class T>
T& deref(T*& t){
  return *t;
}
1 голос
0 голосов
/ 15 июня 2011

Я не знаю, подходит ли это вашему шаблону, но для ссылок на функции-члены boost :: bind и boost :: phoenix уже делают то, что вы хотите:

 struct T 
 {
      void f(int) const {} 
 };


 T instance;
 T* pointer = new T();
 boost::shared_ptr<T> shared(new T());

 boost::bind( & T:f, instance, 1);              // stores instance by value
 boost::bind( & T:f, boost::ref(instance), 2);  // stores instance by ref
 boost::bind( & T:f, boost::cref(instance), 3); // stores instance by const ref

 boost::bind( & T:f, pointer, 4);               // dereferences the pointer

 boost::bind( & T:f, shared, 5);                // dereferences the smart pointer

_Вы даже можете использовать типизацию, чтобы сообщить boost :: bind / phoenix о вашем собственном умном указателе (или любом типе, на который вы хотите разыменовать с помощью оператора * и оператора-> при использовании) _

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...