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,S elect<ENUM_CAST (rank)==ENUM_CA ST(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>::evaluateExp r(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(So meExpr<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<fals e>&) [with T_expr =

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

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

N>::evaluateExp r(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(So meExpr<double, 1>&, Array<double, 2>::Select<fals e>)'

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<fals e>&) [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<doubl e, 2>, Array<double,

2>::Select<true >)

evaluate(expr,S elect<ENUM_CAST (rank)==ENUM_CA ST(T_expr::rank )>());

^

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

N>::evaluateExp r(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<doubl e, 1>, Array<double,

2>::Select<fals e>)

evaluate(expr,S elect<ENUM_CAST (rank)==ENUM_CA ST(T_expr::rank )>());

^

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

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

compilation aborted for stest.cpp (code 2)