#if не для макроса а для имени класса
От: SVV Беларусь  
Дата: 26.02.14 17:06
Оценка:
Всем привет,
пишу функцию-шаблон, тело которой должно зависеть от параметра.

template<typename T>
size_t Align (T *p)
{
#if sizeof(T)<16
    return 10;
#else
    return 20;
#endif
}

как это сделать? компилятору не нравится строка "#if sizeof(T)<16"

еще неплохо бы уметь проверять #if type(T)=="int" и #if defined(Align)

это не троллинг. Всем спасибо за ответы.
Re: #if не для макроса а для имени класса
От: niXman Ниоткуда https://github.com/niXman
Дата: 26.02.14 17:15
Оценка: 1 (1)
используй специализации.

template<typename T>
size_t Align (T *p) {
   return some_template<sizeof(T)>::apply(p);
}
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: #if не для макроса а для имени класса
От: Abyx Россия  
Дата: 26.02.14 18:18
Оценка:
Здравствуйте, SVV, Вы писали:

SVV>
SVV>template<typename T>
SVV>size_t Align (T *p)
SVV>{
SVV>#if sizeof(T)<16
SVV>    return 10;
SVV>#else
SVV>    return 20;
SVV>#endif
SVV>}
SVV>

SVV>как это сделать? компилятору не нравится строка "#if sizeof(T)<16"

Напишите обычный if, компилятор выкинет мертвый код. (И выдаст предупреждение).

SVV>еще неплохо бы уметь проверять #if type(T)=="int" и #if defined(Align)


Для этого курите шаблоны.

SVV>это не троллинг. Всем спасибо за ответы.


Иными словами — RTFM. Не за что.
In Zen We Trust
Re: #if не для макроса а для имени класса
От: jazzer Россия Skype: enerjazzer
Дата: 27.02.14 03:30
Оценка:
Здравствуйте, SVV, Вы писали:

SVV>как это сделать? компилятору не нравится строка "#if sizeof(T)<16"


Как починить — уже сказали, я лишь добавлю, что препроцессинг — это очень ранняя фаза компиляции, когда текст программы — не более чем текст, и никакими типами и шаблонами во время работы препроцессора и не пахнет, их просто не существует еще.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: #if не для макроса а для имени класса
От: TarasB  
Дата: 27.02.14 06:51
Оценка: 1 (1)
Здравствуйте, SVV, Вы писали:

SVV>Всем привет,

SVV>пишу функцию-шаблон, тело которой должно зависеть от параметра.

Можешь написать просто if, компилятор поймёт правильно.

А вообще — это вам в D надо, потому что крестокомитет будет очень долго думать, прежде чем наконец-то одобрит static if
Re: #if не для макроса а для имени класса
От: uzhas Ниоткуда  
Дата: 27.02.14 07:16
Оценка: 4 (2)
Здравствуйте, SVV, Вы писали:

SVV>как это сделать? компилятору не нравится строка "#if sizeof(T)<16"


предположу, что вам нужно это: http://en.cppreference.com/w/cpp/language/alignof
если же хочется именно свой велосипед, то сформулируйте задачу более полно, мы вам предложим решение
то, что вы написали, можно переписать так:
1) http://ideone.com/uCCJNh
2) http://ideone.com/ZkDoN0
Re[2]: #if не для макроса а для имени класса
От: SVV Беларусь  
Дата: 27.02.14 21:15
Оценка:
Здравствуйте, uzhas, Вы писали:

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


SVV>>как это сделать? компилятору не нравится строка "#if sizeof(T)<16"


U>предположу, что вам нужно это: http://en.cppreference.com/w/cpp/language/alignof

U>если же хочется именно свой велосипед, то сформулируйте задачу более полно, мы вам предложим решение
U>то, что вы написали, можно переписать так:
U>1) http://ideone.com/uCCJNh
U>2) http://ideone.com/ZkDoN0
спасибо. я обязательно изучу попозже то что вы написали. на данный момент реализация кажется очень сложной, но чего не сделаешь ради краткости и эффективности клиентского кода.
В D подаваться не планирую
Re[2]: #if не для макроса а для имени класса
От: Vain Россия google.ru
Дата: 27.02.14 22:58
Оценка:
Здравствуйте, TarasB, Вы писали:

TB>А вообще — это вам в D надо, потому что крестокомитет будет очень долго думать, прежде чем наконец-то одобрит static if

а зачем static if отличать от обычного if?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[3]: #if не для макроса а для имени класса
От: TarasB  
Дата: 28.02.14 06:17
Оценка:
Здравствуйте, Vain, Вы писали:

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


TB>>А вообще — это вам в D надо, потому что крестокомитет будет очень долго думать, прежде чем наконец-то одобрит static if

V>а зачем static if отличать от обычного if?

Потому что static if бывает не только в теле функции, но и в другом месте.

Вот как такое сделать на обычном иф?
const int i = 3;

class C {

  static if (i == 3) // ok
    int x;
  else
    long x;

};

Только если разрешить упарываться метом непосредственно на С++
Ну и как бы гарантия, что он отработает на стадии компиляции.
Re: #if не для макроса а для имени класса
От: jazzer Россия Skype: enerjazzer
Дата: 28.02.14 07:46
Оценка: 4 (3) +1
Здравствуйте, SVV, Вы писали:

SVV>Всем привет,

SVV>пишу функцию-шаблон, тело которой должно зависеть от параметра.

SVV>
SVV>template<typename T>
SVV>size_t Align (T *p)
SVV>{
SVV>#if sizeof(T)<16
SVV>    return 10;
SVV>#else
SVV>    return 20;
SVV>#endif
SVV>}
SVV>

SVV>как это сделать? компилятору не нравится строка "#if sizeof(T)<16"

Проще всего так:
return sizeof(T)<16 ? 10 : 20;


вообще выражение sizeof(T)<16 ? 10 : 20 — это выражение времени компиляции, так что можешь использовать его где угодно, хоть в качестве размера массива:
int main()
{
  int x[ sizeof(int)<16 ? 10 : 20 ];
}

jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: #if не для макроса а для имени класса
От: flаt  
Дата: 28.02.14 13:58
Оценка:
Здравствуйте, Vain, Вы писали:

V>а зачем static if отличать от обычного if?


1) условная компиляция — выражений, типов, интерфейсов — аналог #if, но на уровне языка, а не препроцессора
2) условное инстанцирование шаблонов (то, что писалось SFINAE, можно сделать через static if)
Re[2]: #if не для макроса а для имени класса
От: SVV Беларусь  
Дата: 05.03.14 14:55
Оценка:
Здравствуйте, uzhas, Вы писали:

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


SVV>>как это сделать? компилятору не нравится строка "#if sizeof(T)<16"


U>предположу, что вам нужно это: http://en.cppreference.com/w/cpp/language/alignof

U>если же хочется именно свой велосипед, то сформулируйте задачу более полно, мы вам предложим решение
U>то, что вы написали, можно переписать так:
U>1) http://ideone.com/uCCJNh
U>2) http://ideone.com/ZkDoN0
а без std::enable_if можно как-то?
например как скомпилировать код:

template <class T=DWORD>
T ReverseBytes(DWORD &i_rVal, bool i_bReverse)
{
  if(!i_bReverse)
  {
    return i_rVal;
  }
  else
  {
    // here fast implementation
  }
}
template <class T>
T ReverseBytes(T &i_rVal, bool i_bReverse)
{
  if(!i_bReverse)
  {
    return i_rVal;
  }
  else
  {
    T rv = 0;
    byte *pBytesSrc = reinterpret_cast<byte*>(&i_rVal);
    byte *pBytesRet = reinterpret_cast<byte*>(&rv);
    for (size_t i=0,j=sizeof(T)-1; i<sizeof(T); ++i, --j)
      pBytesRet[j] = pBytesSrc[i];
    return rv;
  }
}
template<typename T>
T ReverseBytes (const void *i_pvBuffer, T &val)
{
  return ReverseBytes (*(T*)i_pvBuffer, true);
}

?
ответ видимо тут
template<typename T>
T ReverseBytes (T &i_rVal, bool i_bReverse) {
   return some_template<sizeof(T)>::apply(p);
}

но что это за some_template?
Re[2]: #if не для макроса а для имени класса
От: SVV Беларусь  
Дата: 08.03.14 10:00
Оценка:
Здравствуйте, niXman, Вы писали:

X>используй специализации.


X>
X>template<typename T>
X>size_t Align (T *p) {
X>   return some_template<sizeof(T)>::apply(p);
X>}
X>

прошу подсказать как написать этот some_template
Re[3]: #if не для макроса а для имени класса
От: flаt  
Дата: 08.03.14 16:02
Оценка:
Здравствуйте, SVV, Вы писали:

SVV>прошу подсказать как написать этот some_template


Там куча способов есть. Но смысла это не имеет: http://rsdn.ru/forum/cpp/5493412.1
Автор: jazzer
Дата: 28.02.14


// просто вариант
template<typename T> struct select_size: public std::integral_constant<size_t, (sizeof(T) < 16) ? 10 : 20> {};

template<typename T>
size_t Align (T *p) { return select_size<T>::value; }

// конкретно тот some_template
template<typename T, bool smaller = (sizeof(T) < 16)>
struct some_template
{
  static size_t apply(T*) { return 20; }
};

template<typename T>
struct some_template<T, true>
{
  static size_t apply(T*) { return 10; }
};
Re[4]: #if не для макроса а для имени класса
От: SVV Беларусь  
Дата: 08.03.14 16:57
Оценка:
Здравствуйте, flаt, Вы писали:

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


SVV>>прошу подсказать как написать этот some_template


F>Там куча способов есть. Но смысла это не имеет: http://rsdn.ru/forum/cpp/5493412.1
Автор: jazzer
Дата: 28.02.14


предположим, есть такая штука:
template <class T>
inline void ReverseBytes(T &i_rVal)
{
  BYTE *pBytesSrc = reinterpret_cast<BYTE *>(&i_rVal);
  BYTE *pBytesRet = reinterpret_cast<BYTE *>(&i_rVal);
  size_t uBytesToSwap = sizeof(T)>>1;
  for (size_t i=0,j=sizeof(T)-1; i<uBytesToSwap; ++i, --j)
    SwapBytes(pBytesRet[j], pBytesSrc[i]);
}

для 2 и 4 байтных типов есть быстрая реализация без циклов. фиксированное количество операций. можно конечно писать специализированную функцию для каждого двухбайтного типа, но проще ориентироваться на sizeof(T) и неважно как называется тип (в коде много typedef)

для такого варианта не сильно понятно как шаблон делать. что-то я слабовал в шаблонах. сегодня перечитывал мейерса, про размерность матрицы в шаблоне, но сдается мне там не о том что мне надо речь шла...
template<typename T, size_t size> 
class SquareMatrix: private SquareMatrixBase { 
public: 
  SquareMatrix() // присвоить указателю на данные 
   :SquareMatrixBase<t>(n, 0), // в базовом классе значение null 
    pData(new T(n*n)) // выделить память для данных матрицы, 
    {this->setDataPtr(pData.get();} // сохранить указатель на нее и передать 
... // его копию базовому классу 
private: 
  boost::scoped_array<T> pData; // о классе boost::scoped_array 
}; //см. правило 13
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.