Date: Tue, 3 Oct 2023 18:17:21 +0100
Consider the following template function:
template<typename T>
T *Func(unsigned const arg)
{
static std::string str(arg, 'a');
/* other stuff here */
return nullptr;
}
Let's say it gets instantiated 5 times, with T = [ char, int, double,
std::exception, std::string ], so then we have 5 separate copies of
'str'.
How about if we could specify inside a template function that a
variable is 'static static', meaning that it's shared by all
instantiations? So the following code:
template<typename T>
T *Func(unsigned const arg)
{
static static std::string str(arg, 'a'); //
variable is 'static static'
/* other stuff here */
return nullptr;
}
would be instantiated 5 times something like as follows:
std::optional<std::string> opt_str;
std::once_flag myflag;
char *Func_c(unsigned const arg)
{
std::call_once(myflag, [arg](){ opt_str.emplace(arg,'a'); });
std::string &str = opt_str.value();
/* other stuff here */
return nullptr;
}
int *Func_i(unsigned const arg)
{
std::call_once(myflag, [arg](){ opt_str.emplace(arg,'a'); });
std::string &str = opt_str.value();
/* other stuff here */
return nullptr;
}
double *Func_d(unsigned const arg)
{
std::call_once(myflag, [arg](){ opt_str.emplace(arg,'a'); });
std::string &str = opt_str.value();
/* other stuff here */
return nullptr;
}
std::exception *Func_e(unsigned const arg)
{
std::call_once(myflag, [arg](){ opt_str.emplace(arg,'a'); });
std::string &str = opt_str.value();
/* other stuff here */
return nullptr;
}
std::string *Func_s(unsigned const arg)
{
std::call_once(myflag, [arg](){ opt_str.emplace(arg,'a'); });
std::string &str = opt_str.value();
/* other stuff here */
return nullptr;
}
The only restriction we would need to put in place here is that the
type of the 'static static' variable cannot be dependant upon any of
the template parameters. So for example the following is ill-formed
and the compiler must issue a diagnostic:
template<typename T>
T *Func(unsigned const arg)
{
static static std::vector<T> myvec(arg);
/* other stuff here */
return nullptr;
}
Of course I just picked the syntax out of thin air. Instead of having
"static static", we could perhaps have "template static" or "<static>"
or whatever.
template<typename T>
T *Func(unsigned const arg)
{
static std::string str(arg, 'a');
/* other stuff here */
return nullptr;
}
Let's say it gets instantiated 5 times, with T = [ char, int, double,
std::exception, std::string ], so then we have 5 separate copies of
'str'.
How about if we could specify inside a template function that a
variable is 'static static', meaning that it's shared by all
instantiations? So the following code:
template<typename T>
T *Func(unsigned const arg)
{
static static std::string str(arg, 'a'); //
variable is 'static static'
/* other stuff here */
return nullptr;
}
would be instantiated 5 times something like as follows:
std::optional<std::string> opt_str;
std::once_flag myflag;
char *Func_c(unsigned const arg)
{
std::call_once(myflag, [arg](){ opt_str.emplace(arg,'a'); });
std::string &str = opt_str.value();
/* other stuff here */
return nullptr;
}
int *Func_i(unsigned const arg)
{
std::call_once(myflag, [arg](){ opt_str.emplace(arg,'a'); });
std::string &str = opt_str.value();
/* other stuff here */
return nullptr;
}
double *Func_d(unsigned const arg)
{
std::call_once(myflag, [arg](){ opt_str.emplace(arg,'a'); });
std::string &str = opt_str.value();
/* other stuff here */
return nullptr;
}
std::exception *Func_e(unsigned const arg)
{
std::call_once(myflag, [arg](){ opt_str.emplace(arg,'a'); });
std::string &str = opt_str.value();
/* other stuff here */
return nullptr;
}
std::string *Func_s(unsigned const arg)
{
std::call_once(myflag, [arg](){ opt_str.emplace(arg,'a'); });
std::string &str = opt_str.value();
/* other stuff here */
return nullptr;
}
The only restriction we would need to put in place here is that the
type of the 'static static' variable cannot be dependant upon any of
the template parameters. So for example the following is ill-formed
and the compiler must issue a diagnostic:
template<typename T>
T *Func(unsigned const arg)
{
static static std::vector<T> myvec(arg);
/* other stuff here */
return nullptr;
}
Of course I just picked the syntax out of thin air. Instead of having
"static static", we could perhaps have "template static" or "<static>"
or whatever.
Received on 2023-10-03 17:17:34