用模板参数除以零

时间:2014-12-05 22:43:06

标签: c++ templates

我有一个模板

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

当我用0

实例化它时
Foo<0> bar;

gcc过于聪明,在编译时报告除零

我试过

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

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

但是这给了我错误:

错误:非命名空间范围'class Foo'中的显式特化 错误:template-id'bar&lt; 0&gt;'在主要模板的声明中

任何想法如何解决/解决这个问题?

3 个答案:

答案 0 :(得分:5)

您可以随时重新考虑公式:

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

答案 1 :(得分:4)

您可以为Foo<0>创建模板专精。

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

如果您只想单独使用bar来解决问题,而不是触及Foo的任何其他部分,则可以创建一个配套方法来避免此问题:

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

或者将该方法的实现拉出到自己的类中,并将其专门化:

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

或者,你可以使用Jarod42的建议,并专门研究方法本身(这里重申了答案的完整性)。

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

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

答案 2 :(得分:3)

您可以专门研究该方法:

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

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

Live example

要避免多个定义,您只需要定义一次函数,或者使用内联,所以

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

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

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