2012-09-20 16 views
8

W ramach zespołu programistów chciałem zapewnić, że zestaw funkcji (i operatorów) jest zaimplementowany w niestandardowych iteratorach, które publikujemy. Używanie typów iteratorów STL jako typów bazowych pomaga, jednak z pewnych powodów (poza moją kontrolą) postanawiamy nie wymuszać zgodności STL. Iteratory są zużywane przez ten sam zespół i przez ludzi w całej firmie.static_assert w celu zapewnienia kontraktu projektowego

Chciałem zaprojektować klasę szablonów, która pochłania typ iteratora i testuje na podstawie umowy projektowej.

Na przykład, spodziewałbym się, że iterator będzie implementował operator ++, operator--, a także zadeklaruje wymagane typy.

1> Czy możliwe jest wdrożenie takiej klasy szablonów, która wymusza zawarcie umowy projektowej? prawdopodobnie przy użyciu static_assert?

2> Jeśli tak, czy to dobry projekt?

referencyjny: custom iterator

+1

http: //www.boost.org/doc/libs/1_48_0/libs/type_traits/doc/html/boost_typetraits/category/value_traits/operators.html może? – BoBTFish

+1

[Ładna drukarka] (http://stackoverflow.com/q/4850473/596781) ma klasę cech C++ 11, aby sprawdzić, czy typ zawiera typy iteracyjne i funkcje 'begin' /' end', które zwracają ten iterator rodzaj. –

+0

@Kerrek Dzięki za przykład. Uratowałem kilka godzin roboczych. :) – Ram

Odpowiedz

10

Czy możliwe jest wdrożenie takiej klasy szablonów, która wymusza zawarcie umowy projektowej? prawdopodobnie przy użyciu static_assert?

Dla sprawdzenia, czy istnieje specyficzny sposób (bardzo podobny do 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"); 
} 

jest to dobry projekt?

Tak, bo łamiąc build, błąd zostanie złapany bardzo szybko, a użytkownik klasy doesnt trzeba zapoznać się z dokumentacją (większość ludzi zazwyczaj pominąć tę część w programowaniu)

+0

Czy mogę zapytać, co oznacza test (...)? Nie dostaję tam składni trzech kropek. – DawidPi

+0

@DawidPi Zobacz [funkcja variadic] (http://en.cppreference.com/w/cpp/utility/variadic) –

2

Tak, można zaimplementować taką klasę szablonu. Możesz użyć SFINAE do testowania obecności różnych członków, a jeśli nie są poprawne, static_assert. Chociaż nie jestem pewien, dlaczego chciałbyś zdefiniować typedefs w świecie C++ 11.

Zawsze dobrze jest zrobić dodatkowe sprawdzenie kodu.

Powiązane problemy