【问题标题】:division by zero with a template argument使用模板参数除以零
【发布时间】:2014-12-05 22:43:05
【问题描述】:

我有一个模板

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'中的显式特化 错误:主模板声明中的模板 ID 'bar'

有什么想法可以解决/解决这个问题吗?

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

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

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

    【讨论】:

    • 该死的。正是我想要提出的。 +1
    • 我认为这是最好的方法。不需要额外的代码。
    • 这对这种特定情况有好处 - 个别功能专业化是一个更好的通用答案。
    • 是的,这是示例公式。我的真实情况要复杂得多。当我试图概括时,我应该更加小心。
    【解决方案2】:

    您可以为Foo&lt;0&gt; 创建模板特化。

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

    【讨论】:

    • 这只是一个例子——我的班级远不止这个方法
    • @gsf 然后像 Jaord 那样专门化方法。
    • 除非问题只出在一种或两种方法上,否则我通常更愿意将整个类专门用于基本情况。
    • 这只是一个非常大的类中的一种方法
    • 没有意识到您可以专门化模板类的单个方法...我现在可以简化一些代码!
    【解决方案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; }
    

    【讨论】:

    • 仍在调查,但第一次尝试给了我:`Foo::bar()' 的多重定义
    • @Jacob42 你以前试过这个吗?我无法让它工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多