Я должен предоставить набор перегрузки f
, который принимает указатели на функции-члены и функции-члены:
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);
}
Это прекрасно работает в C ++ 11 и C ++ 14, но не работает C ++ 17, поскольку с P0012R1 спецификатор noexcept является частью типа функции. Для решения этой проблемы необходимо добавить дополнительную перегрузку:
#if __cplusplus >= 201703L
template <typename T, typename Field>
void f(const T& t, Field (T::*getter)() const noexcept) { g((t.*getter)()); }
#endif
Необходим макрос защиты, иначе код не будет компилироваться со старыми стандартами, такими как C ++ 11 или C ++ 14 ( ошибка связана с переопределением шаблона функции).
Как показано выше, реализация обеих перегрузок одинакова. Можно ли обеспечить одну перегрузку, которая работает в C ++ 14 и C ++ 17, без условной компиляции (# if / endif)? Целью является снижение сложности, дублирования кода и бремени тестирования.
Фактический пример использования: https://github.com/Morgan-Stanley/binlog/pull/59/files#diff -043a057ac0b43822d0084562ace76697