I am trying to use data from a std::pair that is returned by a constexpr free function. The first element determines the size of a std::array while the second element is stored in the array.
using DataBundle = std::pair<int, std::pair<int, int>>;
constexpr DataBundle get_data()
{
// other work carried out here
return std::make_pair(1, std::make_pair(2, 3));
}
struct x
{
template<int size>
using OtherData = std::array<std::pair<int, int>, size>;
static constexpr OtherData<get_data().first> foo { get_data().second };
};
The above code isn't as efficient as it could be, as get_data() is called twice in the instantiation of foo. One solution could be to store the returned data as a member of the struct x, as shown below.
// previous code remains the same
struct x
{
template<int size>
using OtherData = std::array<std::pair<int, int>, size>;
static constexpr DataBundle foo_bundle = get_data();
static constexpr OtherData<foo_bundle.first> foo { foo_bundle.second };
};
Although this solution doesn't seem to take full advantage of the template mechanism. So my question is if there is a better approach to this that gets the best out of each of the above samples?
Indeed constexpr function might be computed several times (whereas template class should be instantiated only once), for trivial case as your, first snippet would be fine.
I would create dedicated function/lambda to create foo though:
struct x
{
template<int size>
using OtherData = std::array<std::pair<int, int>, size>;
static constexpr auto foo = []() {
constexpr DataBundle foo_bundle = get_data();
return OtherData<foo_bundle.first>{foo_bundle.second};
} ();
};
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