【问题标题】:prevent template instantiation when template argument is zero当模板参数为零时防止模板实例化
【发布时间】:2012-10-05 07:55:15
【问题描述】:

我有一个模板类

template< std::size_t Size >
class Buffer
{
....
};

我想在 Size 参数为零时阻止此模板的实例化。即为以下内容生成编译器警告。

Buffer< 0 > buf;

但所有其他变体都可以。

Buffer< 10 > buf;

我正在考虑使用 boost::enable_if_c,但我不明白如何让它工作。

--更新-- 不幸的是,我无法使用任何 c++11 功能

【问题讨论】:

    标签: c++ templates boost c++03


    【解决方案1】:

    只需将模板特化为无法实例化的状态:

    template <>
    class Buffer<0>;
    

    这样就无法构造类。使用将导致: error: aggregate ‘Buffer&lt;0&gt; buf’ has incomplete type and cannot be defined

    【讨论】:

    • 无需构造构造函数private。使类无正文,即template&lt;&gt; class Buffer&lt;0&gt;; 足以产生错误。
    • @iammilind:对,我忘记了没有定义的简单声明。编辑为较短的版本。
    【解决方案2】:

    使用BOOST_STATIC_ASSERT 可能更容易:

    #include <boost/static_assert.hpp>
    
    template< std::size_t Size >
    class Buffer
    {
        BOOST_STATIC_ASSERT(Size != 0);
    };
    
    
    int main()
    {
        Buffer<0> b; //Won't compile
        return 0;
    }
    

    【讨论】:

    • +1 + 已接受:因为我的编译器不支持 static_assert,我原本想要一个提升答案:)
    【解决方案3】:

    如果你的编译器支持,试试static_assert:

    template< std::size_t Size >
    class Buffer
    {
        static_assert(Size != 0, "Size must be non-zero");
    
        // ...
    };
    

    【讨论】:

    • +1 我同意如果编译器支持 static_assert,这将是更好的方法,但我的编译器不支持。
    【解决方案4】:
    #include <stddef.h>
    
    typedef ptrdiff_t Size;
    
    template< Size size >
    class Buffer
    {
        static_assert( size > 0, "" );
    };
    
    int main()
    {
    #ifdef  ZERO
        Buffer<0>   buf;
    #else
        Buffer<1>   buf;
    #endif
    }
    

    【讨论】:

    • 这也将fail Buffer&lt;-1&gt;;这不是要求。
    • @iammilind:如果 OP 希望支持缓冲区大小 -1,那么他会发现将条件从 &gt; 更改为 != 很容易。
    • 是的,有趣的是other way 只是typdef unsigned long Size;,所以除了Buffer&lt;0&gt; 之外的所有调用都应该通过。
    • “请解释你的反对意见,以便其他人更容易忽略你未来的反对意见和 cmets” - 好吧,如果他解释得合理,就不会有任何有理由忽略他未来的投票和 cmets 本身,除了个人可能会投票。 iammilind 已经给出了一些理由(不是暗示他或我是反对者)。
    • 考虑到提问者使用size_t 作为模板参数的类型,特别难以认真对待这个概念。这是“无符号类型?我讨厌它们!”提问者代码的版本——使用有符号类型但不包括负值。显然,课程的其余部分可能需要更新以解决这个问题,但由于问题中没有显示,Alf 无法演示它。
    【解决方案5】:

    std::enable_if

    template <std::size_t N, typename = typename std::enable_if<!!N>::type>
    class Matrix {};
    

    static_assert:

    template <std::size_t N>
    class Matrix
    {
        static_assert(N, "Error: N is 0");
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-09
      • 2010-09-18
      • 1970-01-01
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 2019-10-20
      相关资源
      最近更新 更多