【问题标题】:Type trait to match signatures of member functions of different classes键入 trait 以匹配不同类的成员函数的签名
【发布时间】:2018-01-22 12:44:39
【问题描述】:

检查在两个不同类中定义的两个方法的签名是否完全相同的最优雅的方式(可能是 C++17 方式)是什么?

例如:

template< typename ...Ts >
struct A
{
    void f(Ts...);
};

template< typename ...Ts >
struct B
{
    void g(Ts...);
};

static_assert(has_same_signatures< decltype(&A<>::f), decltype(&B<>::g) >{});
static_assert(!has_same_signatures< decltype(&A< int >::f), decltype(&B< char >::g) >{});
//static_assert(has_same_signatures< decltype(&A< void >::f), decltype(&B<>::g) >{}); // don't know is it feasible w/o extra complexity

如果两边的非成员函数类型也允许的话,那就太好了。

也许结果类型也应该被纠缠。

任务源于Qt框架中匹配信号/槽签名的常见问题。

【问题讨论】:

  • @Barry 不要认为,需要和号。您是否认为对函数的引用不够好?
  • 没有&amp;就不能引用非静态成员函数。

标签: c++ qt metaprogramming c++17 typetraits


【解决方案1】:

你可以这样做:

// static member functions / free functions are the same
// if their types are the same
template <class T, class U>
struct has_same_signature : std::is_same<T, U> { };

// member functions have the same signature if they're two pointers to members
// with the same pointed-to type
template <class T, class C1, class C2>
struct has_same_signature<T C1::*, T C2::*> : std::true_type { };

请注意,A&lt;void&gt; 只是格式错误,因为您不能有 void 类型的参数。

【讨论】:

  • "signature" 不包含noexcept-ness 或返回类型,但函数类型包含(noexcept-ness 自 C++17 起);同时,函数类型在 C++20 中不包含 requires-clause,但 "signature" 包含。 OP 需要更准确地指定他们想要什么。
  • 参数类型在哪里?我只看到星号。够了吗?
  • @T.C.哈,这比我想象的要深得多。
  • @Orient 在你的例子中decltype(&amp;A&lt;&gt;::f)void (A::*)() 这也是void() A::*,所以T 会推断为void()
  • @Barry 有趣的符号。鉴于此符号,此 template &lt;class T, class C1, class C2, class ...Ts&gt; struct has_same_signature&lt;T (C1::*)(Ts...), T (C2::*)(Ts...)&gt; : std::true_type { }; 是否过度设计?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-15
  • 1970-01-01
  • 2013-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多