考虑一个只在运行时包装值的类:
template <typename Type>
class NonConstValue
{
public:
NonConstValue(const Type& val) : _value(val) {;}
Type get() const {return _value;}
void set(const Type& val) const {_value = val;}
protected:
Type _value;
};
和constexpr版本:
template <typename Type>
class ConstValue
{
public:
constexpr ConstValue(const Type& val) : _value(val) {;}
constexpr Type get() const {return _value;}
protected:
const Type _value;
};
问题1:您能否确认constexpr版本是否以正确的方式设计?
问题2:如何将这两个类混合成一个名为Value
的类,可以constexpr
构造或运行时构造,其值在运行时或编译时可以是get()
?
编辑:
问题3:如果在get()
文件中定义了.cpp
,并且如果我不希望get()
内联constexpr
,那么该函数的正确声明是什么?是吗
constexpr inline Type get();
或
inline constexpr Type get()
或其他什么?
答案 0 :(得分:19)
只需将constexpr
说明符添加到每个潜在常量表达式的函数中。
template <typename Type>
class Value
{
public:
constexpr Value(Type const& val) : _value(val) {}
constexpr Type const& get() const {return _value;}
void set(Type const& val) {_value = val;}
protected:
Type _value;
};
您不需要 const 和非const 版本,因为可以通过使用实例化模板Value
来完成此操作const 或非const 类型。
您不需要 constexpr 和非constexpr 版本,constexpr
表示潜在的常量表达式以及是否表达式最终成为常量表达式或不依赖于它的参数。表达式是否最终在编译时进行评估取决于上下文和实现。
答案 1 :(得分:2)
您的constexpr
类设计正确,但您错误输入了构造函数的名称(它应该是ConstValue
,而不是Value
)。但我确信这只是一个错字。
constexpr
版本的实例既可以用作编译时也可以用作运行时对象。
template <typename Type>
class ConstValue
{
public:
constexpr ConstValue(const Type& val) : _value(val) {;}
constexpr Type get() const {return _value;}
protected:
const Type _value;
};
int main(int argc, char* argv[])
{
int x[ConstValue<int>(3).get()];
}