如何检查表达式是否为函数名?

时间:2019-04-12 14:15:27

标签: c++ typetraits

问题如标题中所述,该函数可能会被重载或模板化,而这必须在块范围内完成。这是我最好的,但是在函数引用上失败

#include <type_traits>

template <typename... Fs> struct overload : Fs... {
  using Fs::operator()...;
  std::true_type operator()(...);
};

#define is_funcname(f)                                                         \
  [] {                                                                         \
    auto l = [](auto x) mutable                                                \
        -> std::bool_constant<!std::is_pointer_v<decltype(x, f)>> {            \
      return {};                                                               \
    };                                                                         \
    auto o = overload<decltype(l)>{};                                          \
    return decltype(o(42))::value;                                             \
  }()

void bar() {}
void bar(int) {}

void baz() {}

void foo() {
  static_assert(is_funcname(bar));
  static_assert(!is_funcname((void (*)())bar));
  static_assert(is_funcname(baz));
  static_assert(!is_funcname(+baz));

  auto &r = baz;
  static_assert(!is_funcname(r)); // fails
}

用例是我的库必须决定是否需要将表达式捕获为类型擦除的上下文,这在某些平台上可能不受支持,应避免使用。

0 个答案:

没有答案