Reputation: 79
Let's say I have following template C++ class
template<uint32_t FILTER_ORDER, uint32_t BUFFER_LENGTH>
class Filter {
public:
Filter() {}
private:
float data_buffer[BUFFER_LENGTH];
const float filter_coefficients[FILTER_ORDER + 1];
};
I have been looking for a way how I can pass the coefficients of the filter i.e. individual items of the member array filter_coefficients
at compile time. My goal is to have the ability to define filter object in following manner
Filter<3, 8, 1.0, 0.3678, 0.1353, 0.04978> filter;
where the last four non-type arguments of the template are the initialization values for the member array filter_coefficients. Does it exist a way how can I do that in C++?
Upvotes: 1
Views: 80
Reputation: 19113
Yes, it is possible in C++20, before that float
is not allowed as non-type template parameter.
template<uint32_t FILTER_ORDER, uint32_t BUFFER_LENGTH, float...values>
class Filter {
public:
Filter() {}
private:
float data_buffer[BUFFER_LENGTH];
const float filter_coefficients[FILTER_ORDER + 1]{values...};
};
But this embeds the values into the type, is that really what you want? It will prevent storing arrays of these objects because they now have different types.
I would recommend just using constexpr
constructor. Why do you need them to be compile-time anyway?
C++14 variant with constexpr
constructor:
#include <cstdint>
#include <array>
template<std::uint32_t FILTER_ORDER, std::uint32_t BUFFER_LENGTH>
class Filter {
public:
Filter() {}
template<typename...Floats,typename=decltype(std::array<float,FILTER_ORDER+1>{std::declval<Floats>()...})>
constexpr Filter(Floats...floats):filter_coefficients{floats...}{}
private:
// Consider using `std::array` here too.
float data_buffer[BUFFER_LENGTH];
const float filter_coefficients[FILTER_ORDER + 1];
};
int main(){
Filter<3, 4> filter{1.0f,2.0f,3.0f,1.0f};
}
There is basic type check to ensure the elements are float
s, otherwise this variadic template can shadow some other constructors.
Upvotes: 1