First, I have read this very informative answer about stylistic difference between defining a constexpr variable vs constexpr function. My question is more related with the final size of the binary when using these two. Consider this code:
// approach 1
template <typename T>
struct foo
{
static constexpr char name[] = "mickey";
};
// approach 2
template <typename T>
struct bar
{
static constexpr const char* getName() { return "mickey"; }
};
const char* func1() { return foo<int>::name; }
const char* func2() { return foo<double>::name; }
const char* func3() { return bar<int>::getName(); }
const char* func4() { return bar<double>::getName(); }
Look at this code in this godbolt link as well. While approach 1 returns different copies of name, approach 2 returns only one copy for all the different instantiations for different T. Infact, when I created 100 different types approach 2 led to a considerably smaller binary. Was wondering if anyone has experienced something similar.
Well, those two approaches aren't really the same. There are things you can do with foo<T>::name that you cannot do with bar<T>::getName(): I can take a pointer to it and I can take a reference to it. That ability prevents different foo<T>::names from being the same.
But with getName(), there's no such issue. You just get a prvalue - you can't take its address. The different bar<T>::getName functions themselves have to be different, but not the underlying storage.
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