For many RAII "guard" classes, being instantiated as anonymous variables does not make sense at all:
{     std::lock_guard<std::mutex>{some_mutex};     // Does not protect the scope!     // The unnamed instance is immediately destroyed. }     {     scope_guard{[]{ cleanup(); }};     // `cleanup()` is executed immediately!     // The unnamed instance is immediately destroyed. }   From this article:
Anonymous variables in C++ have “expression scope”, meaning they are destroyed at the end of the expression in which they are created.
Is there any way to prevent the user from instantiating them without a name? ("Prevent" may be too strong - "making it very difficult" is also acceptable).
I can think of two possible workarounds, but they introduce syntactical overhead in the use of the class:
Hide the class in a detail namespace and provide a macro. 
namespace detail {     class my_guard { /* ... */ }; };  #define SOME_LIB_MY_GUARD(...) \     detail::my_guard MY_GUARD_UNIQUE_NAME(__LINE__) {__VA_ARGS__}   This works, but is hackish.
Only allow the user to use the guard through an higher-order function.
template <typename TArgTuple, typename TF> decltype(auto) with_guard(TArgTuple&& guardCtorArgs, TF&& f) {     make_from_tuple<detail::my_guard>(std::forward<TArgTuple>(guardCtorArgs));     f(); }   Usage:
with_guard(std::forward_as_tuple(some_mutex), [&] {     // ... });   This workaround does not work when the initialization of the guard class has "fluent" syntax:
{     auto _ = guard_creator()                  .some_setting(1)                  .some_setting(2)                  .create(); }  Is there any better alternative? I have access to C++17 features.
The only sensible way I think about is to make the user pass the result of guard_creator::create to some guard_activator which takes a lvalue-reference as a parameter.
this way, the user of the class has no way but either create the object with a name (the sane option that most developers will do), or new it then dereference (insane options)
for example, you said in the comments you work on a non allocating asynchronous chain creator. I can think on an API which looks like this:
auto token = monad_creator().then([]{...}).then([]{...}).then([]{...}).create(); launch_async_monad(token); //gets token as Token&, the user has no way BUT create this object with a name  
                        If have access to the full potential of C++17, you can expand the idea of using a static factory function into something usefull: guarantied copy elision makes the static factory function possible even for non-movable classes, and the [[nodiscard]] attributes prompts the compiler to issue a warning if the return value is ignored.
class [[nodiscard]] Guard {   public:     Guard(Guard& other) = delete;     ~Guard() { /* do sth. with _ptr */ }     static Guard create(void* ptr) { return Guard(ptr); }   private:     Guard(void* ptr) : _ptr(ptr) {}     void* _ptr; };  int main(int, char**) {   Guard::create(nullptr);   //auto g = Guard::create(nullptr); }   Compile in Compiler Explorer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With