2014-12-05 18 views
6

mam szablondzielenie przez zero z szablonu argumentu

template<size_t N> 
class Foo { 
    int bar(int a) { 
     if (N == 0) 
      return 0; 
     return a/N; 
    } 
} 

kiedy instancję tego z 0

Foo<0> bar; 

gcc jest zbyt inteligentny i raporty dzielenie przez zero w czasie kompilacji

Wypróbowałem

class Foo<size_t N> { 
    template<size_t M> 
    int bar(int a) { 
     return a/N; 
    } 

    template<> 
    int bar<0>(int a) { 
     return 0; 
    } 
}; 

ale to daje mi błąd:

błąd: wyraźnej specjalizacji w zakresie non-namespace 'class Foo' error: template-id 'bar < 0>' w deklaracji pierwotnej matrycy

jakieś pomysły jak mogłem rozwiązać/obejść to?

Odpowiedz

4

Możesz utworzyć specjalizację szablonu dla Foo<0>.

template <> 
class Foo<0> { 
public: 
    bool bar() { return true; } 
}; 

Jeśli chcesz tylko do rozwiązania problemu z bar sam, a nie dotykać innych części Foo można utworzyć metodę towarzysz, aby uniknąć tego problemu:

template <size_t N> 
class Foo 
{ 
    bool bar(int n) { 
     if (n == 0) return true; 
     return 5/n == 1; 
    } 
public: 
    bool bar() { return bar(N); } 
}; 

lub pociągnąć wdrożenie tej metody na zewnątrz do własnej klasy i specjalizują się, że:

template <size_t N> 
class Bar 
{ 
public: 
    bool operator() const { return 5/N == 1; } 
}; 

template <> 
class Bar<0> 
{ 
public: 
    bool operator() const { return true; } 
}; 

template <size_t N> 
class Foo { 
    bool bar() { return Bar<N>()(); } 
}; 

Alternatywnie, można użyć sugestię Jarod42, a specjalizują się m sam eton (odpowiedź powtórzono tutaj dla kompletności).

template <size_t N> 
class Foo 
{ 
public: 
    bool bar() { return 5/N == 1; } 
}; 

template <> inline bool Foo<0>::bar() { return true; } 
+0

to tylko przykład - moja klasa jest o wiele większe niż tylko ten jeden sposób – gsf

+0

@gsf Następnie Specjalizujemy METODY sposób Jaord zrobił. – 0x499602D2

+0

tak, dziękuję, to właśnie próbuję wykonać. – gsf

3

Można specjalizować metodę:

template <size_t N> class Foo 
{ 
public: 
    bool bar() 
    { 
     return 5/N == 1; 
    } 
}; 

template <> 
bool Foo<0>::bar() { return true; } 

Live example

Aby uniknąć wielokrotnych definicji, trzeba zdefiniować funkcję tylko raz, lub użyć inline, więc

// In header 
template <> 
inline bool Foo<0>::bar() { return true; } 

lub

// In header: declaration of the specialization 
template <> 
bool Foo<0>::bar(); 

// in cpp: definition of the specialization. 
template <> 
bool Foo<0>::bar() { return true; } 
+0

wciąż w to zaglądam, ale pierwsza próba daje mi: wiele definicji 'Foo <0u> :: bar() ' – gsf

+0

@ Jacob42 czy próbowałeś tego wcześniej.Nie mogę go uruchomić – gsf

+0

@gsf: edytowane, aby pokazać, jak unikać wielu definicji. – Jarod42

5

Możesz zawsze przemyśleć formułę:

template<size_t N> 
class Foo { 
    bool bar() { 
     return N == 0 || (N >=5 && N < 10); 
    } 
} 
+0

Cholera. Dokładnie to, co chciałem zaproponować. +1 – Columbo

+0

Myślę, że to najlepsze podejście. Nie ma potrzeby stosowania dodatkowego kodu. –

+0

Jest to dobre dla tej konkretnej sytuacji - indywidualna specjalizacja funkcji jest lepszą ogólną odpowiedzią. – Eclipse

Powiązane problemy