Переменная-член C ++ любого типа в не шаблонном классе - PullRequest
3 голосов
/ 20 декабря 2011

Есть ли способ сохранить шаблон или автоматическую переменную в классе, не делая класс шаблоном? Я пытаюсь сохранить указатель на один из генераторов случайных чисел STL, но никак не могу найти способ сделать это без превращения всего класса в шаблон. Это не вариант, так как перемещение всего содержимого файла cpp в h может привести к тому, что в циклический заголовочный файл будет входить множество файлов, с которыми я не хочу иметь дело. Так, например, это будет примерно так:

class tSomeClass
{
    public:
        template<typename RNG>
        tSomeClass(RNG * rng) : fRNG(rng) { }

    private:
        RNG * fRNG; // How do I get this working???
};

Пока все, что я придумал, всегда заканчивалось необходимостью иметь весь класс в качестве шаблона, поэтому я в замешательстве.

РЕДАКТИРОВАТЬ: Я знал, что забыл упомянуть кое-что. Я не могу использовать наследование для указания типа RNG, так как я понятия не имею, что такое база, если кто-то не знает, что такое базовый класс для RNG, используемых STL. В настоящее время я использую std :: default_random_engine.

Ответы [ 3 ]

5 голосов
/ 20 декабря 2011

Я могу придумать два варианта, если вам действительно не нужны шаблоны:

  • Если вы буквально имеете в виду любой тип, вы можете использовать void *.Это не очень безопасно для типов, и пользователи класса должны точно знать, что это за тип, чтобы что-то делать с ним.
  • Если вы можете ограничить тип некоторым базовым интерфейсом / классом, вы можетеиспользуйте вместо этого указатель на этот тип, например IRandom *.Это кажется намного более полезным / пригодным для использования в целом.
0 голосов
/ 20 декабря 2011

Способ C состоит в том, чтобы использовать общий указатель (void*), однако, поскольку это C ++, просто используйте преимущества наследования и динамического связывания, то есть:

class RNG /* random number generator interface/base class */
{
   public:
      virtual int randomize(void) = 0; 
};

class RandomA : public RNG /* one implementation of a random num generator */
{
   public:
      int randomize() { return 4; }
};

class RandomB : public RNG /* another implementation of a random num generator */
{
   public:
      int randomize() { return 0; }
};

class tSomeClass
{
   public:
      tSomeClass(RNG * rng) : fRNG(rng) { }

   private:
      RNG * fRNG;
};

...

RandomA randomObj;
tSomeClass t(&randomObj);

Или даже указатель на функцию подойдет, если это все, из чего состоят ваши генераторы случайных чисел.

0 голосов
/ 20 декабря 2011

Безопасный и правильный способ - определить класс, описывающий интерфейс, и наследовать его в реальных реализациях.

Пример:

class RNG {
    public:
        virtual int get(void) = 0;
}
...