use*_*251 7 c++ local-variables enable-if
我想根据模板 bool 参数有条件地在函数中声明局部变量。因此,如果这是真的,它应该在那里,否则不应该在那里,因为我不希望该变量在堆栈上分配内存或调用其构造函数。它也可以是基本类型。
我无法在 constexpr if 块中声明它,因为我需要用法之间的持久性。
我可以声明变量并添加[[maybe_unused]]. 那么,是否有编译器优化保证不为变量分配内存呢?
template <bool T> void foo()
{
[[maybe_unused]] SomeLargeClass x;
if constexpr(T)
{
/* ... do something with x */
}
/* ... do something without x */
if constexpr(T)
{
/* ... do something more with x */
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试将声明替换为
std::enable_if_t<T, SomeLargeClass> x;
Run Code Online (Sandbox Code Playgroud)
但它不起作用,因为T==false案例无法提供类型。为什么这不是SFINAE?
我还有其他选择吗?
As-if 规则可能会丢弃used SomeLargeClass,但如果该类进行分配,情况会更复杂。一个简单的权衡是在需要时使用std::conditional和拥有SomeLargeClass,在其他情况下使用一些虚拟的小类;
struct Dummy
{
// To be compatible with possible constructor of SomeLargeClass
template <typename ...Ts> Dummy(Ts&&...) {}
};
template <bool B> void foo()
{
[[maybe_unused]] std::conditional_t<B, SomeLargeClass, Dummy> x;
if constexpr(B) {
// ... do something with x
}
// ... do something without x
if constexpr(B) {
// ... do something more with x
}
}
Run Code Online (Sandbox Code Playgroud)
作为替代方案,您可以重写您的函数,使您的类仅位于 constexpr 块中:
template <bool B> void foo()
{
const auto do_something_without_x = [](){
// ... do something without x
};
if constexpr(B) {
SomeLargeClass x;
// ... do something with x
do_something_without_x();
// ... do something more with x
} else {
do_something_without_x();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您的类有一个简单的构造函数,请不用担心 - 编译器不会在堆栈上分配未使用的对象。
如果您的类有一个执行某些工作的构造函数,并且您知道它是浪费的,您可能希望跳过此工作。编译器可能仍然注意到该对象未被使用,并跳过构造函数。在对代码进行任何更改之前检查此项(过早优化)!
但如果构造函数有一些副作用(不推荐),则必须帮助编译器。一种方法是使用unique_ptr:
template <bool T> void foo()
{
unique_ptr<SomeLargeClass> x;
if constexpr(T)
{
... allocate x
... do something with *x
}
... do something without x
if constexpr(T)
{
... do something more with *x
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1250 次 |
| 最近记录: |