template question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Valeriu Catina

    template question

    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)



  • Gianni Mariani

    #2
    Re: template question

    Valeriu Catina wrote:
    ....[color=blue]
    > Array& evaluateExpr(T_ expr expr)
    > {
    > return
    > evaluate(expr,S elect<ENUM_CAST (rank)==ENUM_CA ST(T_expr::rank )>());[/color]

    try :

    evaluate<T>(exp r,Select<ENUM_C AST(rank)==ENUM _CAST(T_expr::r ank)>());

    The problem is obviously in overload resolution and the standard is very
    wordy about how and how not to resolve. I have yet to grok all of that
    but I think that since your implicitly doing a conversion (from Select<>
    to a Select<>&), it is not able to find a corresponding template to
    resolve for.



    Comment

    • Rob Williscroft

      #3
      Re: template question

      Valeriu Catina wrote in news:bmmmf7$dvm $1@f40-3.zfn.uni-bremen.de:
      [color=blue]
      > 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>& )[/color]

      Make this:

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

      or as you've found out yourself:

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

      [snip]
      [color=blue]
      > Array& evaluateExpr(T_ expr expr)
      > {
      > return[/color]

      Here you try to "bind" a temporary ( the Select<...>() ) to a
      non-const reference, this is illegal in Standard C++, the compiler
      that excepts it is probably operating in a msvc v6.0 compatibility
      mode.
      [color=blue]
      > Which compiler is right ?
      >[/color]

      The one('s) that gave you the error.

      HTH

      Rob.
      --

      Comment

      Working...