I have to provide an overload set of f
, that accepts both member and member function pointers:
void g(int) {}
template <typename T, typename Field>
void f(const T& t, Field T::*field) { g(t.*field); }
template <typename T, typename Field>
void f(const T& t, Field (T::*getter)() const) { g((t.*getter)()); }
struct Foo {
int x = 0;
int y() const noexcept { return 1; }
};
int main() {
const Foo foo;
f(foo, &Foo::x);
f(foo, &Foo::y);
}
This works fine in C++11 and C++14, but breaks in C++17, because as of P0012R1, the noexcept specifier is part of the function type. To resolve this, an additional overload has to be added:
#if __cplusplus >= 201703L
template <typename T, typename Field>
void f(const T& t, Field (T::*getter)() const noexcept) { g((t.*getter)()); }
#endif
The macro guard are necessary, otherwise the code does not compile with older standards, such as C++11 or C++14 (the error is about redefinition of a function template).
As shown above, the implementation of both overloads are the same. Is it possible to provide a single overload that works in C++14 and C++17, without conditional compilation (#if/endif)? The goal is reduction of complexity, code duplication and testing burden.
Actual use case: https://github.com/Morgan-Stanley/binlog/pull/59/files#diff-043a057ac0b43822d0084562ace76697