如何定义仅接受具有已定义API的类型的模板函数

时间:2018-04-02 19:42:16

标签: c++ templates c++14 sfinae

template<typename T>
void Func(T& writer)
{
  try
  {
    writer.open("hello.log");
  }
  catch (std::exception & ex) {
    // ...
  }
}

http://en.cppreference.com/w/cpp/types

问题&GT;我是否可以定义模板函数Func只接受具有明确定义的open接口的类型?

谢谢

1 个答案:

答案 0 :(得分:1)

不清楚你为什么要这样做但是...如果你声明(不需要定义)一些辅助函数

template <typename T, typename ... Args>
constexpr auto withOpenHelper (int)
   -> decltype(std::declval<T>().open(std::declval<Args>()...),
               std::true_type{} );

template <typename ... Args>
constexpr std::false_type withOpenHelper (long);

using以简化使用

template <typename T, typename ... Args>
using withOpen = decltype( withOpenHelper<T, Args...>(0) );

只有当Func()支持T接收open()时才能启用/禁用std::string

template <typename T>
std::enable_if_t<withOpen<T, std::string>::value> Func (T & writer)
 {
   // something
 }

以下是一个完整的工作示例

#include <utility>
#include <iostream>
#include <type_traits>

struct A { int open (std::string const &) { return 0; } };
struct B {  };

template <typename T, typename ... Args>
constexpr auto withOpenHelper (int)
   -> decltype(std::declval<T>().open(std::declval<Args>()...),
               std::true_type{} );

template <typename ... Args>
constexpr std::false_type withOpenHelper (long);

template <typename T, typename ... Args>
using withOpen = decltype( withOpenHelper<T, Args...>(0) );

template <typename T>
std::enable_if_t<withOpen<T, std::string>::value> Func (T & writer)
 {
      writer.open("hello.log");
 }

int main ()
 {
   A a;
   B b;

   Func(a);
   //Func(b); // compilation error
 }