Hi,

given the next code:

#define ENUM_CAST(x) int(x)

template<class T,int N>

class Array

{

public:

enum { rank = N };

protected:

// members ...

template<bool>

struct Select{ };

public:

template<class T_expr>

Array& evaluate(T_expr expr, Select<true>& )

{

// ... code

return *this;

}

template<class T_expr>

Array& evaluate(T_expr expr, Select<false>& )

{

// ... code

return *this;

} template<class T_expr>

Array& evaluateExpr(T_expr expr)

{

return

evaluate(expr,Select<ENUM_CAST(rank)==ENUM_CAST(T_ expr::rank)>());

}

public:

// ctors, dtor, function members ...

};

template<class T,int N>

class SomeExpr

{

public:

enum { rank = N };

};

void testFunc()

{

Array<double,2> A;

SomeExpr<double,2> x;

SomeExpr<double,1> y;

A.evaluateExpr(x);

A.evaluateExpr(y);

}

Intel c++ for linux and g++ 3.3.1 do not compile the code (the error

messages are below). In the meantime Intel c++ for Windows compiles it.

If I change the evaluate member functions like below

template<class T_expr>

Array& evaluate(T_expr expr, Select<true> )

{

// ... code

return *this;

}

template<class T_expr>

Array& evaluate(T_expr expr, Select<false> )

{

// ... code

return *this;

}

the compilation succedes.

Which compiler is right ?

Here is the output of the compiler (g++ 3.3.1):

stest.cpp: In member function `Array<T, N>& Array<T,

N>::evaluateExpr(T_expr) [with T_expr = SomeExpr<double, 2>, T = double,

int N = 2]':

stest.cpp:57: instantiated from here

stest.cpp:36: error: no matching function for call to `Array<double,

2>::evaluate(SomeExpr<double, 2>&, Array<double, 2>::Select<true>)'

stest.cpp:21: error: candidates are: Array<T, N>& Array<T,

N>::evaluate(T_expr, Array<T, N>::Select<true>&) [with T_expr =

SomeExpr<double, 2>, T = double, int N = 2]

stest.cpp:28: error: Array<T, N>& Array<T,

N>::evaluate(T_expr, Array<T, N>::Select<false>&) [with T_expr =

SomeExpr<double, 2>, T = double, int N = 2]

stest.cpp: In member function `Array<T, N>& Array<T,

N>::evaluateExpr(T_expr) [with T_expr = SomeExpr<double, 1>, T = double,

int N = 2]':

stest.cpp:58: instantiated from here

stest.cpp:36: error: no matching function for call to `Array<double,

2>::evaluate(SomeExpr<double, 1>&, Array<double, 2>::Select<false>)'

stest.cpp:21: error: candidates are: Array<T, N>& Array<T,

N>::evaluate(T_expr, Array<T, N>::Select<true>&) [with T_expr =

SomeExpr<double, 1>, T = double, int N = 2]

stest.cpp:28: error: Array<T, N>& Array<T,

N>::evaluate(T_expr, Array<T, N>::Select<false>&) [with T_expr =

SomeExpr<double, 1>, T = double, int N = 2]

and Intel (icc) 7.1 for linux:

stest.cpp(37): error: no instance of overloaded function "Array<T,

N>::evaluate [with T=double, N=2]" matches the argument list

argument types are: (SomeExpr<double, 2>, Array<double,

2>::Select<true>)

evaluate(expr,Select<ENUM_CAST(rank)==ENUM_CAST(T_ expr::rank)>());

^

detected during instantiation of "Array<T, N> &Array<T,

N>::evaluateExpr(T_expr) [with T=double, N=2, T_expr=SomeExpr<double, 2>]"

stest.cpp(37): error: no instance of overloaded function "Array<T,

N>::evaluate [with T=double, N=2]" matches the argument list

argument types are: (SomeExpr<double, 1>, Array<double,

2>::Select<false>)

evaluate(expr,Select<ENUM_CAST(rank)==ENUM_CAST(T_ expr::rank)>());

^

detected during instantiation of "Array<T, N> &Array<T,

N>::evaluateExpr(T_expr) [with T=double, N=2, T_expr=SomeExpr<double, 1>]"

compilation aborted for stest.cpp (code 2)