I want to implement the following for more than one (i.e. many) functions (function1(), function2(), ...etc.).
Currently I have it separately as follows:
template <typename T>
concept iterator_1 = requires(T const& t) {
t.function1();
};
template <iterator_1 R>
static float getterFunction(R const& r)
{
return r.function1();
}
template <typename T>
concept iterator_2 = requires(T const& t) {
t.function2();
};
template <iterator_2 R>
static float getterFunction(R const& r)
{
return r.function2();
}
I want to use a general getterFunction to choose function1(), function2(), ...etc. with an if condition, such as follows:
template <typename A>
float getterFunction(A const& a)
{
auto i = -1;
if (something==0) {
i = a.function1();
}
else if (something==1) {
i = a.function2();
}
else if {
...
}
return i;
}
I would like to use this general getterFunction as follows:
template <typename B>
void DoSomething(typename B::iterator const& b)
{
float value = getterFunction(b);
...
}
I was wondering if there is a more general way of doing this, instead of writing many concepts for each of the many functions?
I want to implement the following for more than one (i.e. many) functions (function1(), function2(), ...etc.).
Currently I have it separately as follows:
template <typename T>
concept iterator_1 = requires(T const& t) {
t.function1();
};
template <iterator_1 R>
static float getterFunction(R const& r)
{
return r.function1();
}
template <typename T>
concept iterator_2 = requires(T const& t) {
t.function2();
};
template <iterator_2 R>
static float getterFunction(R const& r)
{
return r.function2();
}
I want to use a general getterFunction to choose function1(), function2(), ...etc. with an if condition, such as follows:
template <typename A>
float getterFunction(A const& a)
{
auto i = -1;
if (something==0) {
i = a.function1();
}
else if (something==1) {
i = a.function2();
}
else if {
...
}
return i;
}
I would like to use this general getterFunction as follows:
template <typename B>
void DoSomething(typename B::iterator const& b)
{
float value = getterFunction(b);
...
}
I was wondering if there is a more general way of doing this, instead of writing many concepts for each of the many functions?
Share Improve this question edited Feb 3 at 10:07 Gyulaxxx asked Feb 1 at 18:18 GyulaxxxGyulaxxx 112 bronze badges 1 |1 Answer
Reset to default 1Since concepts are checked at compile time, you could use if constexpr
which discards any non-taken branch:
template <typename A>
auto getterFunction(A const& a)
{
if constexpr (iterator_1<A>) {
return a.function1();
} else if constexpr (iterator_2<A>) {
return a.function2();
} else {
static_assert(false);
}
}
}
You may want to consider adding a check that only one concept is satisfied, as any type which satisfies more will just use the first one in the checked order. static_assert(std::ranges::count({ iterator_1<A>, iterator_2<A>... }, true) == 1);
should do the trick.
getterFunction
that calls a specific function according to a bunch ofif
statements is not a good sign in terms of design. Unless you absolutely want to use templates, you could as well define some interface class declaringfunction
as virtual and then defines classes that implement this interface. As a consequencegetterFunction
becomes trivial and you can add other implementations without having to changegetterFunction
itself. – edrezen Commented Feb 3 at 11:05