2011-06-13 8 views
16

estoy tratando de escribir algo como:¿Cómo paso una plantilla como parámetro de plantilla a una plantilla?

  // I don't know how this particular syntax should look... 
template<typename template<typename Ty> FunctorT> 
Something MergeSomething(const Something& lhs, const Something& rhs) 
{ 
    Something result(lhs); 
    if (lhs.IsUnsigned() && rhs.IsUnsigned()) 
    { 
     result.SetUnsigned(FunctorT<unsigned __int64>()(lhs.UnsignedValue(), rhs.UnsignedValue())); 
    } 
    else 
    { 
     result.SetSigned(FunctorT<__int64>()(lhs.SignedValue(), rhs.SignedValue())); 
    } 
    return result; 
} 

que se utilizaría como:

Something a, b; 
Something c = MergeSomething<std::plus>(a, b); 

¿Cómo se hace eso?

+0

No sería una simple 'plantilla ' suficiente y luego pasar 'MergeSomething >;' de lo contrario tal vez un pico bajo las tapas de 'boost :: function' o' boost :: bind' podría dar alguna idea – AJG85

+0

@ AJG85: No - si miras el código de ejemplo estoy llamando a la función de plantilla con diferentes argumentos de plantilla dentro de mi propia plantilla de función. –

+0

Ah, sí, así es, supongo que esto es un código simplificado y la determinación del tipo no es tan trivial en realidad. Buena pregunta, creo que podría tener algunas clases genéricas de almacenamiento que podrían beneficiarse de algo como esto. – AJG85

Respuesta

17

Esto es sólo un "argumento de plantilla de la plantilla". La sintaxis es muy cercana a lo que imaginaste. Aquí está:

template< template<typename Ty> class FunctorT> 
Something MergeSomething(const Something& lhs, const Something& rhs) 
{ 
    Something result(lhs); 
    if (lhs.IsUnsigned() && rhs.IsUnsigned()) 
    { 
     result.SetUnsigned(FunctorT<unsigned __int64>()(lhs.UnsignedValue(), rhs.UnsignedValue())); 
    } 
    else 
    { 
     result.SetSigned(FunctorT<__int64>()(lhs.SignedValue(), rhs.SignedValue())); 
    } 
    return result; 
} 

Tu caso de uso debería funcionar como lo publicaste.

11

La forma en que usa es correcta. Pero la definición de su plantilla de función es incorrecta.

Debe ser esto:

template<template<typename Ty> class FunctorT> //<---here is the correction 
Something MergeSomething(const Something& lhs, const Something& rhs) 

Y Ty no es necesario. De hecho, no tiene sentido allí. Puedes omitirlo por completo.

ver este artículo de Stephen C. Dewhurst:

+0

Creo que debes poner un espacio después de la primera "<" para que esto compile con éxito –

+3

@dario_ramos: Está bien: http://www.ideone.com/S639B. Se necesita espacio cuando escribe '>>' que en C++ 03 debería ser '>>'. Esto está arreglado en C++ 0x. – Nawaz

Cuestiones relacionadas