2012-05-03 4 views
6

У меня проблема, с которой я недавно пришел. Я на самом деле думаю, что это невозможно решить, как хотелось бы, но было бы очень удобно, если бы это было возможно. В любом случае, вот в чем проблема:Шаблон специализации псевдонима

Я приведу вам пример, который я видел несколько дней назад на этом форуме, так как с ним будет легче объяснить. Скажем, я пытаюсь создать Tensor-структуру, таким образом:

template <int N> 
struct Tensor 
{ 
    Tensor<N - 1> x; 
    Tensor<N - 1> y; 
    Tensor<N - 1> z; 
}; 

Чтобы избежать бесконечной рекурсии, я бы написать шаблонную специализацию для N = 1.

template<> 
struct Tensor<1> 
{ 
    double x; 
    double y; 
    double z; 
}; 

На самом деле, когда N = 1, этот тензор на самом деле является вектором (физическим). Скажем, у меня уже есть вектор структура определяется следующим образом:

struct Vector 
{ 
    double x; 
    double y; 
    double z; 
}; 

Эта структура точно как Тензор < 1>. Поскольку структура Vector уже существовала и, скажем, я сам ее не реализовал, я хотел бы сделать Tensor < 1> struct алиасом структуры Vector. Так же, как typedef. Таким образом, я хотел бы сделать это таким образом:

// C++03 
typedef Vector Tensor<1>; 

// or C++11 
using Tensor<1> = Vector; 

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

Однако на самом деле невозможно определить специализацию шаблона таким образом. Если бы это было так, я бы не стал задавать этот вопрос.

Примечание: Я знаю, предыдущий пример не является хорошим, так как мы все еще можем сделать это:

using Vector = Tensor<1>; 

Но это довольно надоедливым, если я хочу сделать это с специализаций двух различных структур. Например, при написании библиотеки геометрии, которая может вычислить геометрию в N-мерных пространств:

using Circle<2> = Hypersphere<2>; 

Итак, подведем итог: есть ли способ для создания специализаций шаблонов, определив его как псевдоним другого?

ответ

8

Учитывая унаследованных классов Скалярные, векторные и матричные, вы могли бы использовать наследование:

template<> 
class Tensor<0>: public Scalar {}; 

template<> 
class Tensor<1>: public Vector {}; 

template<> 
class Tensor<2>: public Matrix {}; 

Обратите внимание, что это не злоупотребление наследования, потому что вы моделируя это-отношения.

+0

Да, я уже думал об этом, но если бы я это сделал, классы не были бы «точными». Я имею в виду, что мне пришлось бы использовать cast и down_cast для передачи переменных из одного типа в другой:/ Я знаю, что это всего лишь деталь, и, возможно, это не считается безопасным типом, чтобы мыслить эти классы так, как я, но это точно детали Я бы хотел победить. Спасибо в любом случае :) – Morwenn

+0

@Morwenn Для большей общности вашему примеру понадобится два параметра шаблона: 'template класс Тензор . Здесь D будет числом пространственных измерений. – TemplateRex

+0

Да, но я просто показываю этот пример, чтобы разоблачить синтаксическую проблему. Я сам не использую тензоры.Это было просто для того, чтобы очистить мои мысли о возможностях C++. ^^ « – Morwenn

Смежные вопросы