как в template из ссылочного типа получить базовый?
От: Кодт Россия  
Дата: 19.09.03 14:27
Оценка:
Делаю такую вещь:
template<class T>
struct ByValue : public ByValueBase
{
  T t;

  typedef T Type;
  typedef typename Loki::TypeTraits<T>::ParameterType Param;

  ByValue() {}
  ByValue(Param v) : t(v) {}

  operator T&() { return t; }
  operator Param() const { return t; }
};

Особенность его — в том, что TypeTraits<ByValue<T> >::Param == ByValue<T>; для этих целей я немного расковырял Loki.
Это нужно для функторов, чтобы форсировать передачу туда данных по значению.
А именно — делать устойчивое связывание со временными объектами:
f = BindFirst(functor, something());
.....
f();


Но вот захотелось мне сделать так, чтобы выводить тип функтора, принимающего данные по значению, из функции. Пишу:
using namespace Loki;

template<class R, class P1, class P2, class P3>
Functor<R, TYPELIST_3(ByValue<P1>, ByValue<P2>, ByValue<P3> ) >
make_fn_byval( R(*fn)(P1,P2,P3) )
{
  return Functor<R, TYPELIST_3(ByValue<P1>, ByValue<P2>, ByValue<P3> ) > (fn);
}


Естественно, что
void hello_byval(A,B,C);
void hello_byref(const A&, const B&, const C&);

...
make_fn_byval(hello_byval)(a,b,c); // все окей
make_fn_byval(hello_byref)(a,b,c); // опаньки. Ошибки компиляции


Тупой способ — сделать множество сигнатур
make_fn_byval(R(*fn)(const P1&,P2,P3));
make_fn_byval(R(*fn)(P1,const P2&,P3));
...
// итого 2^n раз, где n - число параметром

В общем, нужен способ из ( Pk | const Pk& ) получить Pk.
Как???
Перекуём баги на фичи!
Re: как в template из ссылочного типа получить базовый?
От: MaximE Великобритания  
Дата: 19.09.03 15:12
Оценка:
Здравствуйте, Кодт, Вы писали:

[]

К>В общем, нужен способ из ( Pk | const Pk& ) получить Pk.

К>Как???

::boost::remove_const<T>::type (требует частичной специализации).

P.S. Александреску писал, что он сам пользует type traits из boost'a, а не из Loki.
Re: как в template из ссылочного типа получить базовый?
От: Павел Кузнецов  
Дата: 19.09.03 15:22
Оценка:
Здравствуйте, Кодт, Вы писали:

template< class T >
struct RemoveRef
{
  typedef T Type;
};

template< class T >
struct RemoveRef< T& >
{
  typedef T Type;
};

#include <iostream>
#include <typeinfo>

int main()
{
  std::cout << typeid(RemoveRef< int        >::Type).name() << std::endl;
  std::cout << typeid(RemoveRef< int&       >::Type).name() << std::endl;
  std::cout << typeid(RemoveRef< const int& >::Type).name() << std::endl;
}


E:\users\pavel\test>cl /GX test.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

test.cpp
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:test.exe
test.obj

E:\users\pavel\test>test
int
int
int
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: как в template из ссылочного типа получить базовый?
От: Кодт Россия  
Дата: 22.09.03 06:03
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>::boost::remove_const<T>::type (требует частичной специализации).


А для VC6|eVC4, значит, нет такого способа?
Код Павла Кузнецова тоже не прокатил...

ME>P.S. Александреску писал, что он сам пользует type traits из boost'a, а не из Loki.


Да, в некоторых местах boost удобнее Loki, но, к сожалению, та часть программы, где мне это понадобилось — уже интегрирована с Loki. Коллеги вряд ли пойдут на отказ от нее.
Ладно, будем объезжать на хромой кобыле.
Перекуём баги на фичи!
Re[3]: как в template из ссылочного типа получить базовый?
От: MaximE Великобритания  
Дата: 22.09.03 10:50
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, MaximE, Вы писали:


ME>>::boost::remove_const<T>::type (требует частичной специализации).


К>А для VC6|eVC4, значит, нет такого способа?

К>Код Павла Кузнецова тоже не прокатил...

Получить тип из ссылки без частичной специализации невозможно. (по-моемому, это и у Павла в статье сказано).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.