具有特定接口的C ++模板专业化

基里尔·切尔尼科夫(Kirill Chernikov)

假设我有这样的模板:

template<class T>
class A
{
   ...
};

我希望只有在将要替换的类型T具有某些接口的情况下,此模板才能被专用例如,此类型必须具有以下两种方法:

int send(const char* buffer, size_t size);
int receive(char* buffer, size_t size);

如何对模板进行此限制?谢谢您的帮助!

UPD:

这个问题是关于SFINAE吗?并非与创造力或课堂设计有关。

Henri Menke

另一个答案显然是可取的,但是由于您明确要求SFINAE,因此您可以执行以下操作:

#include <iostream>
#include <utility>

// std::void_t in C++17
template < typename... >
using void_t = void;


// Check if there is a member function "send" with the signature
// int send(const char*, size_t)
template < typename T >
using send_call_t = decltype(std::declval<T>().send(std::declval<char const *>(), std::declval<size_t>()));

template < typename, typename = void_t<> >
struct is_send_callable : std::false_type {};

template < typename T >
struct is_send_callable< T, void_t< send_call_t<T> > > : std::is_same< send_call_t<T>, int > {};


// Check if there is a member function "receive" with the signature
// int receive(const char*, size_t)
template < typename T >
using recv_call_t = decltype(std::declval<T>().receive(std::declval<char *>(), std::declval<size_t>()));

template < typename, typename = void_t<> >
struct is_recv_callable : std::false_type {};

template < typename T >
struct is_recv_callable< T, void_t< recv_call_t<T> > > : std::is_same< recv_call_t<T>, int > {};


// Make a struct which implements both
struct sndrecv
{
  int send(const char* buffer, size_t size)
  {
    std::cout << "Send: " << buffer << ' ' << size << '\n';
    return 0;
  }

  int receive(char* buffer, size_t size)
  {
    std::cout << "Receive: " << buffer << ' ' << size << '\n';
    return 0;
  }
};


// Disable A if T does not have send and receive
template < typename T, typename >
class A;

template < typename T, typename = typename std::enable_if< is_send_callable<T>::value && is_recv_callable<T>::value >::type >
class A {};


int main() {
  A<sndrecv> a;
//A<int> b; // BOOM!
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章