V
Valeriu Catina
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)
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)