2012-09-20 55 views
8

Como parte de un equipo de desarrolladores, quería asegurarme de que un conjunto de funciones (y operadores) se implementan en los iteradores personalizados que publicamos. Usar tipos de iterador STL como tipos básicos ayuda, sin embargo, debido a algunas razones (fuera de mi control), decidimos no aplicar la compatibilidad STL. Los iteradores son consumidos por el mismo equipo y por personas de toda la compañía.static_assert para garantizar el contrato de diseño

Quería diseñar una clase de plantilla que consuma el tipo de iterador y las pruebas contra el contrato de diseño.

Por ejemplo, esperaría que un iterador implementara un operador ++, operator-- y también declare los typedefs necesarios.

1> ¿Es posible implementar una clase de plantilla que haga cumplir el contrato de diseño? probablemente usando static_assert?

2> En caso afirmativo, ¿es este un buen diseño?

referencia: custom iterator

+1

http: //www.boost.org/doc/libs/1_48_0/libs/type_traits/doc/html/boost_typetraits/category/value_traits/operators.html quizás? – BoBTFish

+1

La [impresora bonita] (http://stackoverflow.com/q/4850473/596781) tiene una clase de rasgo C++ 11 para verificar si un tipo tiene tipos de iterador y funciones 'begin' /' end' que devuelven ese iterador tipo. –

+0

@Kerrek Gracias por el ejemplo. Ahorré varias horas hombre. :) – Ram

Respuesta

10

¿Es posible implementar una clase de plantilla que haga cumplir el contrato de diseño? probablemente usando static_assert?

Para comprobar si existe un método específico (muy similar a this example):

struct Hello 
{ 
}; 

struct Generic { 
    int operator++() 
    { 
     return 5; 
    } 
}; 


// SFINAE test 
template <typename T> 
class has_operator_plusplus 
{ 
    typedef char one; 
    typedef long two; 

    template <typename C> static one test(decltype(&C::operator++)) ; 
    template <typename C> static two test(...); 

public: 
    enum { value = sizeof(test<T>(0)) == sizeof(char) }; 
}; 


int main(int argc, char *argv[]) 
{ 
    // the first check breaks the build 
    //static_assert(has_operator_plusplus<Hello>::value, "has no operator"); 
    static_assert(has_operator_plusplus<Generic>::value, "has no operator"); 
} 

es este un buen diseño?

Sí, porque al romper la acumulación, el error se detecta muy rápido, y el usuario de la clase no dispone de leer la documentación (la mayoría de la gente suele omitir esa parte en la programación)

+0

¿Puedo preguntar qué significa prueba (...)? No entiendo la sintaxis de tres puntos allí. – DawidPi

+0

@DawidPi Ver [función variadic] (http://en.cppreference.com/w/cpp/utility/variadic) –

2

sí, se puede implementar una clase de dicha plantilla. Puede usar SFINAE para probar la presencia de varios miembros y, si no son correctos, static_assert. Aunque no estoy seguro de por qué querría definir typedefs en un mundo C++ 11.

Siempre es una buena idea hacer comprobaciones adicionales en su código.

Cuestiones relacionadas