条件定义变量(static if)
Conditionally defined variable (static if)
在多种情况下,我想使用类似
的东西
template<bool condition>
struct S
{
int value;
if constexpr(condition) /*#if condition*/
double my_extra_member_variable;
/*#endif*/
}
或
if constexpr(sizeof...(Ts) != 0)
// define something extra ( a tuple or so )
这可以通过预处理器标志实现,但我们希望成为不使用预处理器标志而是使用元编程的“酷孩子”
在某些情况下,它也可以与特化一起使用,但假设您有多个条件,并且需要有条件地激活多个成员变量,它可能会很快变得令人讨厌。
我试过了
constexpr in_series_production_mode = false;
struct dummy{ dummy(auto& x){}; operator=(auto& x){return *this;} }; /*1 byte*/
struct debug_data_t { /* lots of parameters with big size*/};
template <typename T>
using maybe_empty = typename std::conditional<in_series_production_mode ,T,dummy>::type;
maybe_empty<debug_data_t> my_debugging_variable;
但是,您仍会为未使用的 dummy
变量获得 1 个字节。而如果您使用 #if
类似的东西,您将需要 0 个字节。
有人知道更好的做法吗?
在 C++20 中,“足够好”的解决方案是使用 [[no_unique_address]]
属性
struct empty_t {};
template<bool condition>
struct S {
[[no_unique_address]]] std::conditional_t<condition, double, empty_t> var;
};
它并不完美,因为 var
总是被定义,但不会占用任何 space。请注意,如果有多个变量,您将需要它们是不同的类型,例如
template<int>
struct empty_t {};
template<bool condition>
struct S {
[[no_unique_address]]] std::conditional_t<condition, double, empty_t<0>> var;
[[no_unique_address]]] std::conditional_t<condition, double, empty_t<1>> rav;
};
在多种情况下,我想使用类似
的东西template<bool condition>
struct S
{
int value;
if constexpr(condition) /*#if condition*/
double my_extra_member_variable;
/*#endif*/
}
或
if constexpr(sizeof...(Ts) != 0)
// define something extra ( a tuple or so )
这可以通过预处理器标志实现,但我们希望成为不使用预处理器标志而是使用元编程的“酷孩子”
在某些情况下,它也可以与特化一起使用,但假设您有多个条件,并且需要有条件地激活多个成员变量,它可能会很快变得令人讨厌。
我试过了
constexpr in_series_production_mode = false;
struct dummy{ dummy(auto& x){}; operator=(auto& x){return *this;} }; /*1 byte*/
struct debug_data_t { /* lots of parameters with big size*/};
template <typename T>
using maybe_empty = typename std::conditional<in_series_production_mode ,T,dummy>::type;
maybe_empty<debug_data_t> my_debugging_variable;
但是,您仍会为未使用的 dummy
变量获得 1 个字节。而如果您使用 #if
类似的东西,您将需要 0 个字节。
有人知道更好的做法吗?
在 C++20 中,“足够好”的解决方案是使用 [[no_unique_address]]
属性
struct empty_t {};
template<bool condition>
struct S {
[[no_unique_address]]] std::conditional_t<condition, double, empty_t> var;
};
它并不完美,因为 var
总是被定义,但不会占用任何 space。请注意,如果有多个变量,您将需要它们是不同的类型,例如
template<int>
struct empty_t {};
template<bool condition>
struct S {
[[no_unique_address]]] std::conditional_t<condition, double, empty_t<0>> var;
[[no_unique_address]]] std::conditional_t<condition, double, empty_t<1>> rav;
};