Передача структуры в качестве шаблона-параметра - Как я могу исправить этот код? - PullRequest
3 голосов
/ 25 сентября 2010

Я пытаюсь скомпилировать следующий код в VC2010.

struct CircValRange
{
    double a,b; // range: [a,b)
};

template <struct CircValRange* Range>
class CircVal
{
    // todo
};


const CircValRange SignedDegRange= {-180., 180.};

CircVal<SignedDegRange> x;

Я получаю

error C2970: 'CircVal' : template parameter 'Range' : 'SignedDegRange' : an expression involving objects with internal linkage cannot be used as a non-type argument
1>          d:\4\circval\circval\circval.h(8) : see declaration of 'CircVal'
1>          d:\4\circval\circval\circval.h(13) : see declaration of 'SignedDegRange'

Я пытаюсь определить шаблонный класс CircVal, который получитstruct Range как шаблонный параметр.

Я не хочу, чтобы была возможность назначать классы с одним диапазоном классам с другим диапазоном (я хочу, чтобы они были разных типов).

Какя могу это сделать?

Ответы [ 4 ]

6 голосов
/ 25 сентября 2010

Кто-то порекомендовал параметр конструктора, который я второй.Но вы все равно можете сделать это как изначально

struct CircValRange
{
    double a,b; // range: [a,b)
};

template <CircValRange const& Range>
class CircVal
{
    // todo
};


extern const CircValRange SignedDegRange= {-180., 180.};

CircVal<SignedDegRange> x;

Но обратите внимание, что свойство, определяющее идентификацию типа CircVal<SignedDegRange>, равно , а не значению SignedDegRange, но адрес / его личность.То есть следующее не работает, потому что CircVal<SignedDegRange1> обозначает другой тип

extern const CircValRange SignedDegRange1 = {-180., 180.};

CircVal<SignedDegRange1> y = x; // error!

Как таковое, перечисление может лучше подходить для этого

enum RangeKind {
  SignedDegRange,
  UnsignedDegRange
};

const CircValRange Ranges[] = { { -180., -180. }, { 0., 360. } };

template <RangeKind Range>
class CircVal
{
    // todo
};

Или даже класса чертсо статическими функциями-членами, похожими на решение, которое кто-то другой имел

template <typename Range>
class CircVal
{
    // todo
};

struct SignedDegRange {
  static double min() { return -180.; }
  static double max() { return  180.; }
};

CircVal<SignedDegRange> x;
4 голосов
/ 25 сентября 2010

Вместо того, чтобы делать его шаблоном, почему бы вам не указать диапазон в качестве параметра конструктора?


struct CircValRange
{
    double a,b; // range: [a,b)
};

class CircVal
{
public:
    CircVal(const CircValRange &_range) : range(_range) {}
private:
    CircValRange range;
    // todo
};


const CircValRange SignedDegRange= {-180., 180.};

CircVal x(SignedDegRange);

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

Или, если вас интересует другой способ с шаблонами, вы можете сделать что-то вроде этого для диапазона:

template <int MIN, int MAX>
class range {
  static const int min = MIN, max = MAX;
};
template <class T>
class CircVal {
  //todo
};

CircVal< range<10,20> > x;

Но, конечно, это не очень чисто или непригодно для использования.

1 голос
/ 25 сентября 2010

Я думаю, что вы пропускаете один шаг.Если вы хотите создать шаблон CircVal, который вы можете специализировать на типе, вы пишете:

template<typename Range>
class CircVal
{
   ...
};

, и если вы затем хотите специализировать его на CircValRange, вы создаете его экземпляр, как вы делаете дальшев вашем коде.

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

1 голос
/ 25 сентября 2010
template <class Range>
class CircVal
{
    // todo
};

или

template <class Range> class CircVal;
template<>
class CircVal<CircValRange> {...

чтобы создать экземпляр

CircVal<CircValRange> ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...