Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用与成员初始化器列表一起使用的静态断言_C++_C++11_Enums_C++14_Static Assert - Fatal编程技术网

C++ 如何使用与成员初始化器列表一起使用的静态断言

C++ 如何使用与成员初始化器列表一起使用的静态断言,c++,c++11,enums,c++14,static-assert,C++,C++11,Enums,C++14,Static Assert,我希望使用static_assert对类的配置实施各种限制。早些时候,我只使用一个枚举,只允许一个构造函数对我的类执行限制,该构造函数需要所述枚举。如果我有下面这样的值,并且范围是从0到4,那么这很好,但是一旦我有了0到500的范围,那么使用枚举就变得很难了 某个班级 class Some_Class { public: Some_Class(const unsigned int param); private: const unsigned in

我希望使用static_assert对类的配置实施各种限制。早些时候,我只使用一个枚举,只允许一个构造函数对我的类执行限制,该构造函数需要所述枚举。如果我有下面这样的值,并且范围是从0到4,那么这很好,但是一旦我有了0到500的范围,那么使用枚举就变得很难了

某个班级

class Some_Class {
    public:
        Some_Class(const unsigned int param);
    private:
        const unsigned int member_param;
};
某个_Class.cpp

Some_Class::Some_Class(const unsigned int param) : member_param(param) {
    static_assert(member_param < 500, "Param must be less than 500.");
};
这就是GCC在使用C++14编译时对我提出的问题:

1>  Some_Class.cpp: In constructor 'Some_Class::Some_Class(unsigned int)':
1>C:\some_path\Some_Class.cpp(3,2): error : non-constant condition for static assertion
1>    static_assert(member_param < 500, "Param must be less than 500.");
1>    ^
1>C:\some_path\Some_Class.cpp(3,2): error : use of 'this' in a constant expression
1>Some_Class.cpp:在构造函数“Some_Class::Some_Class(unsigned int)”中:
1> C:\some\u path\some\u Class.cpp(3,2):错误:静态断言的非常量条件
1> 静态断言(成员参数<500,“参数必须小于500”);
1>    ^
1> C:\some\u path\some\u Class.cpp(3,2):错误:在常量表达式中使用“this”

如果要进行编译时检查,应使用模板:

template<int size>
class Some_Class {
public:
    Some_Class() : member_param(size) { static_assert(size < 500, "Size should be less than 500"); }
private:
    const unsigned int member_param;
}

如果有人从类派生并将构造函数公开,则会在构造函数中添加普通断言。

如果要进行编译时检查,应使用模板:

template<int size>
class Some_Class {
public:
    Some_Class() : member_param(size) { static_assert(size < 500, "Size should be less than 500"); }
private:
    const unsigned int member_param;
}

如果有人从类派生并将构造函数公开,则会在构造函数中添加普通断言。

参数值不能在constexpr中使用

您必须以某种方式提交编译时值:

  • 为整个班级制作模板:

    template<unsigned int size>
    class Some_Class {
        static_assert(size < 500, "Size should be less than 500");
    public:
        constexpr unsigned int member_param = size;
    };
    
    模板
    上课{
    静态_断言(大小<500,“大小应小于500”);
    公众:
    constexpr unsigned int member_param=size;
    };
    
  • 传递积分_常数:

    template <unsigned int N>
    using uint_c = std::integral_constant<unsigned int, N>;
    
    class Some_Class {
    public:
        template<unsigned int size>
        Some_Class(uint_c<size>) : member_param(size)
        {
            static_assert(size < 500, "Size should be less than 500");
        }
    private:
        unsigned int member_param;
    };
    
    模板
    使用uint_c=std::积分_常数;
    上课{
    公众:
    模板
    某些类(uint c):成员参数(大小)
    {
    静态_断言(大小<500,“大小应小于500”);
    }
    私人:
    无符号整数成员_参数;
    };
    

参数值不能在constexpr中使用

您必须以某种方式提交编译时值:

  • 为整个班级制作模板:

    template<unsigned int size>
    class Some_Class {
        static_assert(size < 500, "Size should be less than 500");
    public:
        constexpr unsigned int member_param = size;
    };
    
    模板
    上课{
    静态_断言(大小<500,“大小应小于500”);
    公众:
    constexpr unsigned int member_param=size;
    };
    
  • 传递积分_常数:

    template <unsigned int N>
    using uint_c = std::integral_constant<unsigned int, N>;
    
    class Some_Class {
    public:
        template<unsigned int size>
        Some_Class(uint_c<size>) : member_param(size)
        {
            static_assert(size < 500, "Size should be less than 500");
        }
    private:
        unsigned int member_param;
    };
    
    模板
    使用uint_c=std::积分_常数;
    上课{
    公众:
    模板
    某些类(uint c):成员参数(大小)
    {
    静态_断言(大小<500,“大小应小于500”);
    }
    私人:
    无符号整数成员_参数;
    };
    

如果有人做了某类foo6(GetCurrentTimeinMillimes()%1000),该怎么办?静态断言在编译时执行。函数参数在运行时传递。我建议一个常规的断言。啊,该死,我刚刚意识到。有没有办法在编译时对构造函数强制执行函数参数检查,或者这实际上只是一个新问题?也许在某种程度上抛出constexpr可能会有所帮助。@NeilKirk我使用的是一个相对最小的嵌入式系统,因此即使经过优化,assert添加的~4KB代码对我的环境来说也太多了。我希望使用static_assert,因为根据我的理解,它应该引入最小甚至零的额外代码大小。什么?在发布版本中通常禁用断言。4kb是从哪里来的?如果有人做了某个类foo6(getCurrentTimeInMillissions()%1000),该怎么办?静态断言在编译时执行。函数参数在运行时传递。我建议一个常规的断言。啊,该死,我刚刚意识到。有没有办法在编译时对构造函数强制执行函数参数检查,或者这实际上只是一个新问题?也许在某种程度上抛出constexpr可能会有所帮助。@NeilKirk我使用的是一个相对最小的嵌入式系统,因此即使经过优化,assert添加的~4KB代码对我的环境来说也太多了。我希望使用static_assert,因为根据我的理解,它应该引入最小甚至零的额外代码大小。什么?在发布版本中通常禁用断言。4kb从何而来?为什么不让构造函数成为一个模板?@NeilKirk这是一个有趣的想法,但在谷歌快速搜索并编写了一些代码之后,我似乎无法让构造函数成为一个模板。根据你的评论,我正在为我的原始答案添加一个替代方案。为什么不让构造函数成为一个模板呢?@NeilKirk这是一个有趣的想法,但在谷歌快速搜索并编写了一些代码之后,我似乎无法让构造函数成为一个模板。根据你的评论,我在我原来的答案的基础上添加了一个替代答案。
template <unsigned int N>
using uint_c = std::integral_constant<unsigned int, N>;

class Some_Class {
public:
    template<unsigned int size>
    Some_Class(uint_c<size>) : member_param(size)
    {
        static_assert(size < 500, "Size should be less than 500");
    }
private:
    unsigned int member_param;
};