2011-11-24 22 views
5

Tengo un código genérico que implementa la regla de Pareto. Parece un código bien formado.error de "expresión primaria esperada" en el método de plantilla que usa

GCC 4.4 mensajes del compilador sobre errores para newResult.set<Criterion>(criterion()); expresión. Pero no puedo encontrar el problema.

registro de error completo:

trunk$ g++ -std=c++0x -o test test.cpp 
t6.cpp: In member function ‘bool Pareto<Minimize<T>, Types ...>::operator()(Map&, Map&)’: 
t6.cpp:24: error: expected primary-expression before ‘>’ token 
t6.cpp:26: error: expected primary-expression before ‘>’ token 
t6.cpp:26: error: expected primary-expression before ‘)’ token 
t6.cpp:26: error: expected primary-expression before ‘>’ token 
t6.cpp:26: error: expected primary-expression before ‘)’ token 
t6.cpp: In member function ‘bool Pareto<Maximize<T>, Types ...>::operator()(Map&, Map&)’: 
t6.cpp:43: error: expected primary-expression before ‘>’ token 
t6.cpp:45: error: expected primary-expression before ‘>’ token 
t6.cpp:45: error: expected primary-expression before ‘)’ token 
t6.cpp:45: error: expected primary-expression before ‘>’ token 
t6.cpp:45: error: expected primary-expression before ‘)’ token 

código completo anuncio:

// TypeMap 
template < typename ... Tail > 
struct Holder; 

template <typename ValueType, typename Head, typename ... Tail > 
struct Holder<ValueType, Head, Tail ... > : 
    public Holder<ValueType, Head>, 
    public Holder<ValueType, Tail ... > 
{}; 

template <typename ValueType, typename Head > 
struct Holder<ValueType, Head> 
{ 
    ValueType value; 
}; 

template < typename ... Types > 
struct TypeMap; 

template <typename ValueType, typename ... Types > 
struct TypeMap<ValueType, Types ... > : 
    public Holder<ValueType, Types ... > 
{ 
    template <typename T> 
    void set(const ValueType& value) 
    { 
     ((Holder<ValueType, T>*)this)->value = value; 
    } 

    template <typename T> 
    ValueType get() 
    { 
     return ((Holder<ValueType, T>*)this)->value; 
    } 
}; 

// Objectives 
template <typename Criterion> struct Maximize : public Criterion {}; 
template <typename Criterion> struct Minimize : public Criterion {}; 

// Criteria 
struct Criterion1{ double operator()(){ return 0; }}; 
struct Criterion2{ double operator()(){ return 0; }}; 

// Pareto rule 
template < typename ... Types > struct Pareto; 

template < typename T, typename ... Types > 
struct Pareto<Minimize<T>, Types ... > 
{ 
    template< typename Map > 
    bool operator()(Map& oldResult, Map& newResult) 
    { 
     typedef Minimize<T> Criterion; 
     Criterion criterion; 

     // ERROR HERE !!! 
     newResult.set<Criterion>(criterion()); 

     if(newResult.get<Criterion>() >= oldResult.get<Criterion>()) 
      return false; 

     Pareto<Types ... > pareto; 
     return pareto(oldResult, newResult); 
    } 
}; 

template < typename T, typename ... Types > 
struct Pareto<Maximize<T>, Types ... > 
{ 
    template< typename Map > 
    bool operator()(Map& oldResult, Map& newResult) 
    { 
     typedef Maximize<T> Criterion; 
     Criterion criterion; 

     // ERROR HERE !!! 
     newResult.set<Criterion>(criterion()); 

     if(newResult.get<Criterion>() <= oldResult.get<Criterion>()) 
      return false; 

     Pareto<Types ... > pareto; 
     return pareto(oldResult, newResult); 
    } 
}; 

template<> 
struct Pareto<> 
{ 
    template<typename Map> 
    bool operator()(Map& oldResult, Map& newResult) 
    { 
     oldResult = newResult; 
     return true; 
    } 
}; 

int main() 
{ 
    TypeMap<double, Minimize<Criterion1>, Maximize<Criterion2>> oldResult, newResult; 

    Pareto<Minimize<Criterion1>, Maximize<Criterion2>> pareto; 
    pareto(oldResult, newResult); 
} 
+0

código interesante ... ¿qué hacer? +1 de todos modos – sehe

+0

Me alegro de que hayas preguntado esto ... Me llevó para siempre encontrar la causa a través de este hilo. ++ 1 – AlmostSurely

Respuesta

8

Encontrado:

newResult.template set<Criterion>(criterion()); 

if(newResult.template get<Criterion>() >= oldResult.template get<Criterion>()) 
    return false; 

usted tiene que calificar las plantillas de función miembro para el compilador, en este caso . El analizador léxico no sería capaz de decidir (en el momento de la declaración de plantilla , no instanciación) si <Criterion significa el comienzo de una lista de parámetros de plantilla o, en cambio, un operador de comparación.

Ver

  • Using the template keyword as qualifier

  • What is the .template and ::template syntax about? (Comeau)

  • estándar, § 14.2, sub 4. y 5., cabe destacar:

    [Nota: como en el caso del prefijo typename, el prefijo de plantilla está permitido en los casos en que es no estrictamente necesario; es decir, cuando el especificador de nombre anidado o la expresión a la izquierda de -> o. no es dependiendo de un parámetro de plantilla, o el uso no aparece en el alcance de una plantilla. nota -fin]

+0

** Actualizado ** encontrado el culpable. (Considere proporcionar una pequeña explicación sobre lo que su código está tratando de hacer, me tomó bastante tiempo entenderlo solo con el nombre (críptico)) – sehe

Cuestiones relacionadas