Adding bitwise operations and conversion-to-bool to scoped enums - a Christmastide exploration : <p>Let's say that I'm crazy and decided to create the following monstrosity:</p>

<pre><code>#include &lt;type_traits&gt;
#include &lt;iostream&gt;

// Utility proxy type - convertible back to E but also permits bool conversion
// for use in conditions.
// 
//  e.g.
//   Foo f = Foo::Bar &amp; Foo::Baz;
//   if (f &amp; Foo::Baz) { /* ... */ }
// 
template &lt;typename E, typename = std::enable_if_t&lt;std::is_enum_v&lt;E&gt;, void&gt;&gt;
struct EnumToBoolProxy
{   
    operator E() const
    {
        return _val;
    }

    explicit operator bool()
    {
        using UT = std::underlying_type_t&lt;E&gt;;
        return static_cast&lt;UT&gt;(_val) != 0;
    }

private:
    const E _val;

    EnumToBoolProxy(const E val) : _val(val) {}

    friend EnumToBoolProxy operator&amp;(const E, const E);
    friend EnumToBoolProxy operator|(const E, const E);
};


enum class Foo
{
    Bar = 1, Baz = 2, Boi = 4
};

EnumToBoolProxy&lt;Foo&gt; operator&amp;(const Foo lhs, const Foo rhs)
{
    using UT = std::underlying_type_t&lt;Foo&gt;;
    return static_cast&lt;Foo&gt;(static_cast&lt;UT&gt;(lhs) &amp; static_cast&lt;UT&gt;(rhs));
}

EnumToBoolProxy&lt;Foo&gt; operator|(const Foo lhs, const Foo rhs)
{
    using UT = std::underlying_type_t&lt;Foo&gt;;
    return static_cast&lt;Foo&gt;(static_cast&lt;UT&gt;(lhs) | static_cast&lt;UT&gt;(rhs));
}


int main()
{
    // Good
    if ((Foo::Bar | Foo::Baz) &amp; Foo::Baz)
        std::cout &lt;&lt; "Yay\n";

    // Fine
    const bool isFlagSet((Foo::Bar | Foo::Baz) &amp; Foo::Baz);
    std::cout &lt;&lt; isFlagSet &lt;&lt; '\n';

    // Meh
    auto proxyThing = (Foo::Bar | Foo::Baz) &amp; Foo::Baz;
}
</code></pre>

<p>The goal is to:</p>

<ol>
<li>Have a scoped enum such that values are <code>Foo::x</code> and are of type <code>Foo</code> (symmetry!)</li>
<li>Be able to do some "bitwise" arithmetic on them and get a <code>Foo</code> back</li>
<li>Be able to check the result for zero-ness</li>
<li>But not let people generally use the enum as an arithmetic type</li>
</ol>

<p>For fun, I'm trying to avoid:</p>

<ol>
<li>Using a bog-standard enum</li>
<li>Doing this instead with free functions <code>IsFlagSet</code></li>
</ol>

<p>Ignoring for a second the incongruity of not being able to do the zero-ness check without a prior <code>&amp;</code>- or <code>|</code>-operation&hellip;</p>

<p>It seems like a shame that my users can still "get" a <code>EnumToBoolProxy</code> (i.e. <code>proxyThing</code>). But, since it is not possible to add any members to <code>Foo</code>, and since <code>operator bool</code> must be a member, I can't seem to find any other way to go about this.</p>

<p>Granted that's not a real problem as they can't do much with the <code>EnumToBoolProxy</code>. But it still feels like an abstraction leak, so I'm curious: am I right in saying that this is just inherently impossible? That there's no way to "pick and choose" a scoped-enum's opacity like this? Or is there some way to hide this proxy type while still using as a conversion-to-bool facility to check the "result" of the <code>&amp;</code>/<code>|</code> operations? How would you do it?</p>
