Reputation: 7252
I have a template
template<size_t N>
class Foo {
int bar(int a) {
if (N == 0)
return 0;
return a / N;
}
}
when I instantiate this 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 error:
error: explicit specialization in non-namespace scope 'class Foo' error: template-id 'bar<0>' in declaration of primary template
any ideas how I could solve/workaround this?
Upvotes: 6
Views: 612
Reputation: 70422
You can create a template specialization for Foo<0>
.
template <>
class Foo<0> {
public:
bool bar () { return true; }
};
If you only want to address the issue with bar
alone, and not touch any other part of Foo
, you can create a companion method to avoid the issue:
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 that method out into its own class, and specialize 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 Jarod42's suggestion, and specialize the method itself (answer reiterated here for completeness).
template <size_t N>
class Foo
{
public:
bool bar() { return 5 / N == 1; }
};
template <> inline bool Foo<0>::bar() { return true; }
Upvotes: 4
Reputation: 217438
You may specialize the method:
template <size_t N> class Foo
{
public:
bool bar()
{
return 5 / N == 1;
}
};
template <>
bool Foo<0>::bar() { return true; }
To avoid multiple definitions, you have to define the function only once, or use inline, so
// 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; }
Upvotes: 3
Reputation: 45493
You can always rethink the formula:
template<size_t N>
class Foo {
bool bar() {
return N == 0 || (N >=5 && N < 10);
}
}
Upvotes: 5