Preventing users from creating unnamed instances of a class : <p>For many <strong>RAII "guard"</strong> classes, being instantiated as anonymous variables does not make sense at all:</p>

<pre><code>{
    std::lock_guard&lt;std::mutex&gt;{some_mutex};
    // Does not protect the scope!
    // The unnamed instance is immediately destroyed.
}
</code></pre>

<p></p>

<pre><code>{
    scope_guard{[]{ cleanup(); }};
    // `cleanup()` is executed immediately!
    // The unnamed instance is immediately destroyed.
}
</code></pre>

<p>From <a href="http://www.learncpp.com/cpp-tutorial/814-anonymous-variables-and-objects/" rel="noreferrer">this article</a>:</p>

<blockquote>
  <p>Anonymous variables in C++ have “expression scope”, meaning they are destroyed at the end of the expression in which they are created.</p>
</blockquote>

<hr>

<p><strong>Is there any way to prevent the user from instantiating them without a name?</strong> <em>("Prevent" may be too strong - "making it very difficult" is also acceptable).</em></p>

<p>I can think of two possible workarounds, but they introduce syntactical overhead in the use of the class:</p>

<ol>
<li><p>Hide the class in a <code>detail</code> namespace and provide a macro. </p>

<pre><code>namespace detail
{
    class my_guard { /* ... */ };
};

#define SOME_LIB_MY_GUARD(...) \
    detail::my_guard MY_GUARD_UNIQUE_NAME(__LINE__) {__VA_ARGS__}
</code></pre>

<p>This works, but is <em>hackish</em>. </p></li>
<li><p>Only allow the user to use the guard  through an higher-order function.</p>

<pre><code>template &lt;typename TArgTuple, typename TF&gt;
decltype(auto) with_guard(TArgTuple&amp;&amp; guardCtorArgs, TF&amp;&amp; f)
{
    make_from_tuple&lt;detail::my_guard&gt;(std::forward&lt;TArgTuple&gt;(guardCtorArgs));
    f();
}
</code></pre>

<p>Usage:</p>

<pre><code>with_guard(std::forward_as_tuple(some_mutex), [&amp;]
{
    // ...
});
</code></pre>

<p>This workaround does not work when the initialization of the guard class has "fluent" syntax:</p>

<pre><code>{
    auto _ = guard_creator()
                 .some_setting(1)
                 .some_setting(2)
                 .create();
}
</code></pre></li>
</ol>

<p>Is there any better alternative? I have access to C++17 features.</p>
