2

I'm interested to understand the source of the following error:

'.' cannot appear in a constant-expression

I already know how to solve this thanks to this link: '.' and constant-expression

As a matter of fact I have the same problem as the problem described in the link above. I just want to understand why reverting the comparison makes it work. thanks. this is my code:

template <typename Key> std::vector<Segment<Key> > findIntersections(const Interval<Key> &interval ,Segment<Key> segment)
{
Interval<Key> *x = &interval;
vector<Segment<Key> > intersections;

while( x!= NULL)
{
    if(x->intersects(segment.gety1(),segment.gety2())) intersections.push_back(segment);
    else if (x->left == NULL)                x = x->right;
    //else if (x->left->max < segment.gety1()) x = x->right;//this line gives the error
    else if (segment.gety1() > x->left->max) x = x->right;//this line is OK
    else                                     x = x->left;
}
return intersections;
}

EDIT1

I provide bellow a bit more code accompanying the code above.

Interval<Key>

defines a geometric interval (don't pay attention on the comments):

template <class Key> class Interval
{
public:
    Key low;
    //Key high;//previous implementation
    std::vector<Key> high;//to implement... may be better to use a max priority queue
                          //A priority queue is better since accessing a value is in o(log N) - vector is in o(N)
                          //as well deleting and inserting is in o(log N) for priority queue
                          //a binary tree is good as well.
    Key max;//to implement
    Key back;//represent the maximum of the list of high
    bool color;
    int N; //number of nodes under this subtree
    Interval *left, *right;
    Interval(Key lo, Key hi, Key val, bool c): low(lo),max(val),back(val),color(c),N(1),left(NULL),right(NULL)
    {
        high.push_back(hi);
    }
    bool intersects(Key lo, Key hi);
};

the Segment class:

template <class Type> class Segment
{
private:
    Type x1, y1, x2, y2;

public:
    Segment(Type x1, Type y1, Type x2, Type y2):x1(x1), y1(y1), x2(x2), y2(y2){}
    inline bool isHorizontal(){return x1 == x2;}
    inline bool isVertical  (){return y1 == y2;}
    int compare(Segment segment);
    inline Type getx1(){return x1;}
    inline Type getx2(){return x2;}
    inline Type gety1(){return y1;}
    inline Type gety2(){return y2;}

};

and finally the intersects method:

template <class Key> bool Interval<Key>::intersects(Key lo, Key hi)
{
if(lo <= this->low && this->back <= hi) return true;
if(this->low <= lo && hi <= this->back) return true;
if(lo <= this->low && hi <= this->back) return true;
if(this->low <= lo && this->back <= hi) return true;
return false;

} 

Let me know if you need more... thanks all for your help...

EDIT2

I'm using a gcc 4.6.1 compiler for windows: MinGW-32 bits

Community
  • 1
  • 1
PhonoDots
  • 149
  • 1
  • 12
  • 3
    Please provide minimal code that repro's the issue. – Luchian Grigore Dec 10 '13 at 10:33
  • I voted to close this since it really only asks for clarification of the answer provided in the question you linked and doesn't seem to add anything new. Still an interesting question. – Benjamin Bannier Dec 10 '13 at 10:34
  • 2
    @BenjaminBannier Unfortunately, the answers in the possible duplicate are totally useless. – juanchopanza Dec 10 '13 at 10:36
  • @juanchopanza: Very true. It really depends if the goal is to collect a definite list of good answers to good questions or if we just plan to handle a never-ending stream of questions. But that's all meta. – Benjamin Bannier Dec 10 '13 at 10:40
  • What compiler are you using? (Also, what are `Segment`, `Interval`? are there from a library?) – gx_ Dec 10 '13 at 10:41
  • @juanchopanza What do you mean? If you need more code, I'll provide it... Let me know! – PhonoDots Dec 10 '13 at 10:41
  • 2
    @PhonoDots Provide a minimal-length example that we can compile ourselves. See http://sscce.org/ – interjay Dec 10 '13 at 10:43
  • Btw, in `findIntersections`, given `const Interval &interval`, the declaration `Interval *x = &interval;` is illegal, and you should get an “error: invalid conversion from ‘`const Interval*`’ to ‘`Interval*`’” on that line. (And your member functions should probably all be `const`.) – gx_ Dec 10 '13 at 11:33
  • @gx_ I get no compilation errors at all at this line... – PhonoDots Dec 10 '13 at 11:37
  • @PhonoDots Maybe you never instantiate `findIntersections` (I can't tell with the partial code that you showed). Anyway, I can't reproduce your error with the g++4.6 on http://gcc.godbolt.org/ (but I don't have Windows/mingw) – gx_ Dec 10 '13 at 11:43

2 Answers2

2

Are you using namespace std; anywhere in your code? That is the only way, I could reproduce your error. See here. It looks like, that compiler is treating max as a template function and hence treating < as the start of the argument list.

PS: Your code ran fine in MSVC 2013 Express irrespective of whether I have using namespace std in the code.

Also this link may explain more about your question.

Community
  • 1
  • 1
benipalj
  • 704
  • 5
  • 9
0

It seems the compiler is somehow (macro witchery seems most probable) induced to think that the < sign following the max identifier is not comparison operator but an opening template parameter-list bracket. Therefore what is following must, it expects, be either a type name or a constant expression.

ach
  • 2,314
  • 1
  • 13
  • 23