First, I am not sure why you need so much code for make_string
. I'd simply define it as
template<class... Args>
inline std::string make_string(Args&&... args)
{
ostringstream ostr;
_do{ostr << std::forward<Args>(args)...};
return std::move(ostr.str());
}
where
struct _do { template <typename... T> _do(T&&...) { } };
is a helper struct that lets you evaluate expressions in the right order (but watch out, GCC incorrectly evaluates right-to-left until 4.9 at least).
Now, to your question. As I said in my comment, I feel your problem is irrelevant to make_string
. In Undefined reference to static class member, in my question passing a static constexpr variable by universal reference?, and in all relevant questions I've seen, the suggested answer is that one defines the variable somewhere out of class:
constexpr int foo::max_offset;
I'm not sure if this is a problem for you. It is a problem for me because in heavily templated code it implies too much duplication (see discussion below my question). Anyhow, if it is a problem, I see a few other simple solutions to ensure call-by-value:
use
make_string(..., int(max_offset))
instead ofmake_string(..., max_offset)
as a shortcut,
+max_offset
does the same job (suggested here)define
static constexpr int max_offset() { return some_value; }
, then usemax_offset()
instead ofmax_offset
throughoutlet some part of code (function or template) deduce
max_offset
as a non-typeint
template parameter, then use it directlylastly, define
make_string(Args... args)
(this is the simplest but does not apply here as you don't want to copy all those strings)
I am not discussing use of make_string
in throwing an exception; this is a different problem.