如果我的 class 是文字 class 那么将我的 class 的对象声明为 constexpr 是多余的吗?
If my class is a literal class then is it redundant to declare an object of my class as constexpr?
我有一个constexpr class调试:
struct Debug {
constexpr Debug(bool a, bool b, bool c) : a(a), b(b), c(c) {}
bool a, b, c;
constexpr bool get() const { return a; }
};
int main() {
Debug dbg(true, false, false); // is dbg constexpr object?
constexpr Debug dbg2(0, 0, 0); // is constexpr redundant here?
}
如您所见,dbg
是一个 constexpr 对象,因为它是用 constexpr 构造函数初始化的,所以如果我用 constexpr 限定它,那有什么意义呢?
- 我不知道
dbg
和 dbg2
之间的区别。谢谢。
有一个主要区别:在需要常量表达式的地方只能使用dbg2
。例如,考虑即将推出的允许任意 non-type 模板参数的 C++20 功能:
template <Debug> void f() { }
根据上面的定义,f<dgb2>()
会编译,而f<dgb>()
不会。
f<dgb>();
<source>:7:29: note: template argument deduction/substitution failed:
<source>:13:12: error: the value of 'dbg' is not usable in a constant expression
13 | foo<dbg>(); // ERROR
| ^
<source>:10:9: note: 'dbg' was not declared 'constexpr'
10 | Debug dbg(true, false, false); // is dbg constexpr object?
这在 C++11 中也很重要。你可以说:
template <bool> void g() { }
g<dgb2.a>();
但不是:
g<dgb.a>();
两个变量有何不同的简单演示:
struct Debug {
constexpr Debug(bool a, bool b, bool c) : a(a), b(b), c(c) {}
bool a, b, c;
constexpr bool get() const { return a; }
};
int main() {
Debug dbg(true, false, false); // dbg is not a constant
constexpr Debug dbg2(0, 0, 0); // constexpr makes this a constant expression
// *** Begin demo ***
dbg.a = false;
//dbg2.a = false; //< error: assignment of member 'Debug::a' in read-only object
// *** End demo ***
}
dbg
的值可以修改,dbg2
的值不可以。
要获得作为常量表达式的 Debug
对象,您需要构造函数中的 constexpr
限定符(以允许将 Debug
对象标记为常量表达式) 和变量声明中的 constexpr
限定符(将该对象标记为常量表达式)。
我有一个constexpr class调试:
struct Debug {
constexpr Debug(bool a, bool b, bool c) : a(a), b(b), c(c) {}
bool a, b, c;
constexpr bool get() const { return a; }
};
int main() {
Debug dbg(true, false, false); // is dbg constexpr object?
constexpr Debug dbg2(0, 0, 0); // is constexpr redundant here?
}
如您所见,dbg
是一个 constexpr 对象,因为它是用 constexpr 构造函数初始化的,所以如果我用 constexpr 限定它,那有什么意义呢?
- 我不知道
dbg
和dbg2
之间的区别。谢谢。
有一个主要区别:在需要常量表达式的地方只能使用dbg2
。例如,考虑即将推出的允许任意 non-type 模板参数的 C++20 功能:
template <Debug> void f() { }
根据上面的定义,f<dgb2>()
会编译,而f<dgb>()
不会。
f<dgb>();
<source>:7:29: note: template argument deduction/substitution failed: <source>:13:12: error: the value of 'dbg' is not usable in a constant expression 13 | foo<dbg>(); // ERROR | ^ <source>:10:9: note: 'dbg' was not declared 'constexpr' 10 | Debug dbg(true, false, false); // is dbg constexpr object?
这在 C++11 中也很重要。你可以说:
template <bool> void g() { }
g<dgb2.a>();
但不是:
g<dgb.a>();
两个变量有何不同的简单演示:
struct Debug {
constexpr Debug(bool a, bool b, bool c) : a(a), b(b), c(c) {}
bool a, b, c;
constexpr bool get() const { return a; }
};
int main() {
Debug dbg(true, false, false); // dbg is not a constant
constexpr Debug dbg2(0, 0, 0); // constexpr makes this a constant expression
// *** Begin demo ***
dbg.a = false;
//dbg2.a = false; //< error: assignment of member 'Debug::a' in read-only object
// *** End demo ***
}
dbg
的值可以修改,dbg2
的值不可以。
要获得作为常量表达式的 Debug
对象,您需要构造函数中的 constexpr
限定符(以允许将 Debug
对象标记为常量表达式) 和变量声明中的 constexpr
限定符(将该对象标记为常量表达式)。