Альтернатива шаблонному объявлению typedef - PullRequest
4 голосов
/ 14 сентября 2010

Я пытаюсь выполнить

namespace NTL
{
    typedef std::valarray vector;
}

через стандартный C ++. Я знаю, что это запрещено, но мне нужен быстрый и простой способ (без переопределения всех функций, операторов, перегрузок и т. Д.) Получить шаблон typedef.

Сейчас я делаю шаблонный класс Vector, в котором в качестве члена данных используется valarray, но для этого потребуется перегрузить все математические функции для моего вектора (опять же ... как это делает valarray).

Есть идеи? Спасибо!

PS: Мне, возможно, понадобится в какой-то момент расширить функциональность NTL::vector, и способ включить это в решение будет потрясающим.

Ответы [ 2 ]

8 голосов
/ 14 сентября 2010

В C ++ 0x это будет действительно просто, но в настоящее время вы можете подойти к проблеме двумя способами: с помощью мета-функции или злоупотребления наследованием.

namespace NTL {
   // metafunction
   template <typename T>
   struct vector_1 {
      typedef std::valarray<T> type;
   };

   // inheritance abuse:
   template <typename T>
   struct vector_2 : std::valarray<T>
   {};
}
int main() {
   NTL::vector_1<double>::type var1; // type is std::valarray<double>
   NTL::vector_2<double> var2;       // type inherits from std::valarray<double>
}

Второй подход может быть легко расширен, но обратите внимание, что в общем случае не рекомендуется публично наследовать от контейнеров STL, поскольку они не предназначены для расширения. В частности, поскольку у них нет виртуального деструктора, вы можете получить неопределенное поведение, если ваш объект находится в delete d от указателя на контейнер STL ...

Я бы посоветовал вам наследовать в частном порядке и перенести базовые функции-члены в область видимости посредством декларации using (лучше, чем предоставление публичного наследования). Для этого потребуется больше кода, но вам не нужно будет предоставлять методы переадресации для всех желаемых интерфейсов.

Кстати, путь C ++ 0x будет:

namespace NTL {
   template <typename T>
   using vector = std::valarray<T>;
}
1 голос
/ 14 сентября 2010

Вы можете получить класс NTL::vector из std::valarray:

namespace NTL {
  template <class T>
  class vector : public std::valarray<T>
  {
  public:
    vector() : std::valarray<T>() { }
    vector(const std::valarray<T>& other) : std::valarray(other) { }
    /* other constructors to match the std::valarray constructors */

    vector& operator=(const vector& );
    vector& operator=(const std::valarray<T>& );
  };
}

Таким образом, NTL::vector преобразуется в std::valarray в начале последовательности операций, но результирующий valarray также может быть снова преобразован в NTL::vector.

Одно большое предупреждение: поскольку stl::valarray не предназначен для полиморфного использования, у вас возникнут проблемы, если вы попытаетесь удалить объект NTL::vector через указатель std::valarray!

...