LINUX.ORG.RU

[C++] Шаблоны и макросы

 


0

0

Как в макрос передать имя типа шаблона. т.е. есть макрос:

#define CLASS(x) My##x##Class 
И есть шаблонный класс:
class MyClass {...};
class MyintClass : public MyClass {...};
class MydoubleClass : public MyClass {...};

template <typename T>
class Manager
{
  Manager()
  {
    c = CLASS( T );
  }
  MyClass c;
}
Хочется чтоб при указании Manager<int> использовался класс MyintClass. Но при такой реализации компилятор ругается, что не нашел тип MyTClass. ЧЯДНТ?


> ЧЯДНТ?

Не понимаешь, в каком порядке происходит обработка исходников. _Пре_процессор, который разворачивает макросы, вызывается до компилятора, который разворачивает шаблоны, как и следует из названия.

kemm
()
Ответ на: комментарий от Torvus

> Я догадался, но можноли как-то решить эту проблему?

Ты сначала скажи какую именно проблему ты пытаешься решить таким странным способом.

Deleted
()

Кстати. Почему нельзя разделить объявление и реализацию шаблонного класса по разным файлам (.h и .cpp)?

Torvus
() автор топика
Ответ на: комментарий от Torvus

>Кстати. Почему нельзя разделить объявление и реализацию шаблонного класса по разным файлам (.h и .cpp)?

Неизвестно, какую специализацию выносить в объектник, ну и export templates не поддерживается используемым компилятором.

bose
()
Ответ на: комментарий от Torvus

> Я догадался, но можноли как-то решить эту проблему?

В том виде, в каком ты озвучил -- нет. Потому что пока это звучит так: "хочу сделать так, как противоречит работе препроцессора и компилятора C++". Если ты скажешь, что именно и для чего тебе нужно получить -- вероятно, проблема решаема.

kemm
()
Ответ на: комментарий от Deleted

> Ты сначала скажи какую именно проблему ты пытаешься решить таким странным способом.

Таким странным способом я пытался переложить часть своей работы на компилятор. Т.е. вместо того, чтобы использовать большой switch, сделать так чтобы программа сама определяла какой именно класс ей нужен:

class Manager
{
  enum Type { Int, Double, ... }
  Manager( Type t )
  {
    switch( t )
    {
      case Int:
        c = MyintClass;
        break;
      case Double:
        c = MydoubleClass;
        break;
      ...
      ...
      ...
    }
  }
  MyClass c;
}

Torvus
() автор топика
Ответ на: комментарий от Torvus

А зачем тебе разные классы? Почему не использовать template<typename T> MyClass?

kemm
()
Ответ на: комментарий от Torvus

>Т.е. вместо того, чтобы использовать большой switch, сделать так чтобы программа сама определяла какой именно класс ей нужен

Тут нужен ассоциативный массив вида {идентификатор типа -> функция возвращающая инстанс}. То есть фабрика.

Absurd ★★★
()
Ответ на: комментарий от Deleted

>Ты сначала скажи какую именно проблему ты пытаешься решить таким странным способом.
сдается мне, он пишет калькулятор :)

xydo ★★
()

>Хочется чтоб при указании Manager<int> использовался класс MyintClass.

Читай про специализацию шаблонов. Вроде как именно такое поведение тебе требуется.

staseg ★★★★★
()
Ответ на: комментарий от Torvus

У тебя в голове перепуталось время компиляции и время выполнения программы. Подобного поведения можно достигнуть в скриптовых языках, но никак не в С++. Я бы оставил свитч, если сильно не нравится, Absurd говорит верную идею.

Legioner ★★★★★
()

Ты (или кто-то другой) __давно__ сделал что-то неправильно, так что тебе надо рассказывать с самого начала.


> Хочется чтоб при указании Manager<int> использовался класс MyintClass.


Костыль делается легко.

template<class T> struct Util {};

#define DECLARE_MY(c) template<> Util<c> { typedef My##c##class my_class; }

DECLARE_MY(int);
DECLARE_MY(double);
...

и потом
template<class T> Manager
{
... MyClass* x = new Util<T>::my_class(); ...
};

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

struct пропустил, вот так надо:

#define DECLARE_MY(c) template<> struct Util<c> { typedef My##c##class my_class; }

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Legioner

Да пусть глянет выхлоп gcc -E фаел.цхх
Вроде все станет очевидным, я так думаю.

l5k
()

В общем, решил не заморачиваться и оставить switch. Всем спасибо за ответы.

Torvus
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.