Image you have a struct as follows:
struct DataParameters {
int a;
int b[2];
int c;
};
In a specific situation, you know all these values at compile time:
constexpr DataParameters p = {
.a = 5,
.b = {3, 3},
.c = 12
};
You then want to create a template function which uses the values of a, b, c. The following syntax is valid since the struct is declared as constexpr
.
template<int A, int B_0, int B_1, int C>
void doSomething() {
...
}
doSomething<p.a, p.b[0], p.b[1], p.c>();
But let's say you have a struct that is much bigger and you do not want a giant list of template parameters. Is there any better way to it? I've tried the following, but get compiler errors:
template<const DataParameters& P>
void doSomething() {
...
}
doSomething<p>();
Any suggestions?
Since C++11 you can have template <const DataParameters& P>
with objects that have static storage duration and either external or internal linkage.
Since C++17 you can have template <const DataParameters& P>
with objects that have static storage duration (the linkage restriction was removed)
Since C++20 you can have template <DataParameters P>
. The non-type parameter can be (since C++20):
- a literal class type with the following properties:
- all base classes and non-static data members are public and non-mutable and
- the types of all bases classes and non-static data members are structural types or (possibly multi-dimensional) array thereof.
https://en.cppreference.com/w/cpp/language/template_parameters
struct DataParameters // don't use C style typedef
{
int a;
int b[2];
int c;
};
template <const DataParameters& x>
void foo() {}
constexpr DataParameters gp{};
void test_ref_global()
{
foo<gp>(); // ok since C++11
}
void test_ref_local()
{
static constexpr DataParameters p{};
foo<p>(); // ok since C++17
}
template <DataParameters x> // ok since C++20
void bar() {}
auto test_val()
{
constexpr DataParameters p{};
bar<p>(); // ok since C++20
}