Division by zero with template argument

I have a template

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

when i create an instance with 0

 Foo<0> bar; 

gcc is too smart and reports division by zero at compile time

I tried

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

but this gives me an error:

error: explicit specialization in the non-space namespace 'class Foo' error: template-id 'bar <0>' in the primary template declaration

any ideas how i could solve / handle this?

+6
source share
3 answers

You can create a custom specialization for Foo<0> .

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

If you want to solve the problem only with bar and not touch any other part of Foo , you can create a companion method to avoid the problem:

 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); } }; 

Or pull the implementation of this method into your class and indicate that:

 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>()(); } }; 

Alternatively, you can use the Jarod42 proposal and specialize the method itself (the answer is repeated here for completeness).

 template <size_t N> class Foo { public: bool bar() { return 5 / N == 1; } }; template <> inline bool Foo<0>::bar() { return true; } 
+4
source

You can always revise the formula:

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

You can specialize the method:

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

Living example

To avoid multiple definitions, you need to define the function only once or use inline, therefore

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

or

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

Source: https://habr.com/ru/post/979200/


All Articles