Open ricardomatias opened 10 months ago
You might have oversimplified your actual problem. In the example you provided, your public interface should take gsl::span
or std::span
and you can optionally provide convenience functions for std::array
if the span
conversions in user code are not to your liking. Then your private implementation can have optimized versions for specific sizes based on your needs, and fall back to generic implementations for other sizes.
//library.hpp
#include <gsl/span>
namespace library
{
using gsl::span;
void createDecreasingOdds(span<float_t>, int k);
void sumDistribution(span<float_t const> probabilities, span<float_t> results);
}
//library.cpp
#include <library.hpp>
namespace library
{
void createDecreasingOdds(span<float_t> s, int k)
{
switch(std::size(s))
{
case 0: return;
case 1: return createDecreasingOddsOptimized<1>(s, k);
case 2: return createDecreasingOddsOptimized<2>(s, k);
case 3: return createDecreasingOddsOptimized<3>(s, k);
//...
default: break;
}
//generic implementation
return;
}
void sumDistribution(span<float_t const> probabilities, span<float_t> results)
{
if(std::size(probabilities) != std::size(results))
{
//error handling / contract violation
return;
}
switch(std::size(probabilities))
{
case 0: return;
case 1: return sumDistributionOptimized<1>(probabilities, results);
case 2: return sumDistributionOptimized<2>(probabilities, results);
case 3: return sumDistributionOptimized<3>(probabilities, results);
//...
default: break;
}
//generic implementation
return;
}
}
//user code.cpp
#include <library.hpp>
#include <array>
static constexpr std::size_t const S{10};
int main()
{
std::array<float_t, S> a;
library::createDecreasingOdds(a, 123);
return a.front();
}
If your actual problem is more complex than that, then I'm not sure it could be covered in a bite-sized episode, since it really depends on a lot of different factors. Public API design is a whole field of its own.
Thanks for the feedback @LB--, I wasn't aware of std::span. In my case the library is for embedded development, so I can't have any dynamic allocations and structure sizes have to be defined beforehand.
Channel "C++Weekly"
Topics What is the appropriate way of hiding implementation details with template specialization?
Imagine you have the following function declaration inside a header file:
In the end this function will be used in another function to compose the final behavior that you actually want to expose (as a library f.ex) to the user. The problem is that the implementation can't be inside a .cpp file due
std::size_t N
, which would have to be implemented for every number needed (which is unknown, therefore might as well be considered infinite). If a class is considered, then that defeats the purpose as well, because you'd need different instances of the same class specialized to the size of the desired container (referring here tostd::size_t N
.Example of what is wanted:
The episode should be about what needs to be done in the perspective of someone making a library and how to approach this problem.
Length Bite-Sized