我想使用static_assert来强制我的类配置的各种限制。之前我只想使用一个枚举,只允许一个构造函数需要枚举来强制限制我的类。如果我有类似下面的内容并且范围是从0到4,这可以正常工作,但是一旦我有0到500的范围,那么使用枚举变得笨拙。
Some_Class.h
class Some_Class {
public:
Some_Class(const unsigned int param);
private:
const unsigned int member_param;
};
Some_Class.cpp
Some_Class::Some_Class(const unsigned int param) : member_param(param) {
static_assert(member_param < 500, "Param must be less than 500.");
};
Main.cpp的
Some_Class foo4(125); // OK
Some_Class foo5(500); // Should fail at compile time.
这是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
答案 0 :(得分:2)
参数值不能用于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;
};
传递一个integral_constant:
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;
};
答案 1 :(得分:1)
如果您想要编译时检查,您应该使用模板:
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;
}
然后使用该类,用户必须明确指定大小:
void myFunction() {
Some_Class<20> class20; // Works
Some_Class<500> class500; // Compiler error
}
编辑:基于来自@NeilKirk的评论,以下代码将实现相同而不必将整个类作为模板:
class Some_Class {
public:
template<int size>
static Some_Class* createClass() {
static_assert(size < 500, "Size should be less than 500");
return new Some_Class(size);
}
private:
Some_Class(int size) : member_param(size) { assert(size < 500); }
private:
const unsigned int member_param;
};
它的作用:构造函数接受大小但是是私有的。因此,必须使用作为模板的createClass
静态函数创建类,并且可以对大小执行static_assert。
创建对象:
Some_Class* class = Some_Class::createClass<20>();
如果有人从类派生并使构造函数公开,则在构造函数中添加正常断言以供例如。