【发布时间】:2020-03-25 15:35:31
【问题描述】:
我必须提供一个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
【问题讨论】:
标签: c++ templates c++17 generic-programming