For similar use cases without member functions

void f(MyClass c);

f(g_obj);

 

you could use implicit conversion

class MyClassProvider {

    operator MyClass() { return GetMyClass(); };

};

MyClassProvider g_obj;
 

to get a custom function called for each usage to get a MyClass from g_obj

 

I am sure you know this, just want to show the similarity of this approach. Also to see, whether there is a more general possible new feature or generalization of an existing C++ feature behind your idea.

 

-----Ursprüngliche Nachricht-----
Von: Frederick Virchanza Gotham via Std-Proposals <std-proposals@lists.isocpp.org>
Gesendet: Di 25.07.2023 00:24
Betreff: [std-proposals] Functions that don‘t need parentheses to make a call
An: std-proposals <std-proposals@lists.isocpp.org>;
CC: Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>;
You'll occasionally see the following inside C++ files:

   MyClass &GetMyClass(void)
   {
       static MyClass obj;
       return obj;
   }

   #define g_obj (GetMyClass())

Since C++11, this code uses a "once_flag" behind the scenes to make
sure that it's threadsafe.

The only problem here with using the preprocessor to define 'g_obj' is
that we can't control the scope -- we can't put 'g_obj' inside a
namespace. We also need to make sure that nobody names anything
'g_obj' anywhere.

But, what if we could remove the preprocessor from the equation by
providing a syntax for functions to take "void void" instead of
"void". So we would define the function as follows:

   MyClass &g_obj(void void)
   {
       static MyClass obj;
       return obj;
   }

So now in our code wherever we write "g_obj", it's as if we had
written "g_obj()".

Then we could do stuff like:

   std::optional<T> g_opt;

   T &g_obj(void void)
   {
       if ( false == g_opt.has_value() ) std::abort();

       return g_opt.value();
   }

We could also apply a constraint that the function must return an
L-value reference.

If you don't like the "void void" then we could have another syntax like:

   T &g_obj =
   {
       if ( false == g_opt.has_value() ) std::abort();

       return g_opt.value();
   };

Using this alternative syntax, we could even put it inside a function body:

int main(void)
{
   T &g_obj =
   {
       if ( false == g_opt.has_value() ) std::abort();

       return g_opt.value();
   };

   g_obj.SomeMethod();
}

P.S. Totally unrelated to this, in a couple of days I'll post a paper
on NRVO working with over a dozen compilers
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals