使用 require 子句仅有条件地存在成员变量

10 c++ templates c++-concepts c++20

member我希望使内部的存在dat依赖于B(或其他一些概念)。

template <bool B>
struct dat {
    void member_func() requires (B) {} //ok
    std::byte member requires (B); //err
};
Run Code Online (Sandbox Code Playgroud)

我知道这可能与专业化有关,但据我所知,如果需要多个不同的成员要求,那会变得非常难看。

如果没有专门化,这种行为是否可能?

Bar*_*rry 10

有几种方法可以实现这一点(请参阅有条件成员)。

一种是使用条件来更改 的类型member

struct E { };
[[no_unique_address]] std::conditional_t<B, std::byte, E> member;
Run Code Online (Sandbox Code Playgroud)

这并不是真正的条件成员变量,member它始终存在。但有时它是您关心的类型,有时它是不占用空间的空类型。这可能已经足够好了 - 如果您实际上不需要访问该事物,并且没有代码依赖于该成员的存在。

如果这不起作用,那么你就必须求助于不同类型的专业化。但您不必专门化所有dat,只需有条件地提供此成员的基类即可:

template <bool B>
struct maybe_member {
   std::byte member;
};

template <>
struct maybe_member<false> { };

template <bool B>
struct dat : maybe_member<B> {
    void member_func() requires (B) {} //ok
};
Run Code Online (Sandbox Code Playgroud)

这里dat<true>有一个名为成员memberdat<false>没有数据成员iterator_category这对于诸如(正如我提到的)之类的事情很重要。


两者都不是很好的解决方案,但两者都绝对胜过仅仅为了以成员变量为条件而专门化整个类。如果需要多个不同的、独立的条件变量,则两者都会缩放。