如何检查成员函数或自由函数是否适用于确切的给定类型(而不是其任何基类)?

fel*_*lix 3 c++ template-meta-programming c++17 c++20

检查是否可以在对象上调用成员函数/自由函数的方法是:

#include <type_traits>
#include <utility>

template <class T, class = void>
struct HasMember : std::false_type {};
template <class T>
struct HasMember<T, std::void_t<decltype(std::declval<T>().Foo())>> : std::true_type {};

template <class T, class = void>
struct HasFreeFoo : std::false_type {};
template <class T>
struct HasFreeFoo<T, std::void_t<decltype(Foo(std::declval<T>()))>> : std::true_type {};

struct A { void Foo() {} }; 
struct B : A {};
struct C : B {};
                                          
void Foo(const A &) {}

int main() {
  static_assert(HasMember<C>::value, "");
  static_assert(HasFreeFoo<C>::value, "");
}
Run Code Online (Sandbox Code Playgroud)

但正如示例所示,

  1. CFoo被认为已经A实施了会员Foo
  2. C被认为自acceptFoo以来已经实现了free函数。Fooconst A &

我想要实现的就是拥有HasMember<A>::value == true && HasMember<C>::value == falseHasFreeFoo<A>::value == true && HasFreeFoo<C>::value == false。欢迎任何帮助,谢谢。

背景:我正在实现一个 ser/des 工具,用户可以选择实现成员函数或自由函数来指定类型应如何获取 ser/des。我需要检查这样的成员函数/自由函数是否完全针对给定类型实现(不是从其基类继承)。

康桓瑋*_*康桓瑋 5

HasMember和的实现HasFreeFoo是合理的,因为确实可以通过继承C获得。Foo()您需要的是实现另一个特征来选择是通过成员函数还是通过自由函数调用。例如:

template <class T, class = void>
struct UseMemberFoo : std::false_type {};

template <class T>
struct UseMemberFoo<T, std::enable_if_t<HasMember<T>::value && !HasFreeFoo<T>::value>>
 : std::true_type { };

template<class T>
void Foo(const T&) = delete;

template <class T, class = void>
struct UseFreeFoo : std::false_type {};

template <class T>
struct UseFreeFoo<T, std::enable_if_t<HasMember<T>::value && HasFreeFoo<T>::value>>
 : std::true_type { };
Run Code Online (Sandbox Code Playgroud)

T只有 member 时Foo(),则通过成员函数调用它。当用户继承有成员的基类Foo()并为派生类提供free函数时,然后通过free函数调用它。

演示。