条件定义变量(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;
};