检查c ++中是否存在具有给定签名的函数

时间:2011-01-17 20:01:19

标签: c++ templates metaprogramming

所以我一直在寻找检查具有特定参数的函数是否存在的方法。我有一个模板化的方法,它依赖于一个外部函数(来自类的外部)来完成这项工作:

  template <class Moo>
  void exportDataTo(Moo& ret){
     extended_solid_loader(ret, *this);
  }

在项目的多个点上,我有一些宏,它们为不同的类型定义了extended_solid_loader,但是现在我希望能够使用默认函数,如果还没有为该特定的类类型定义extended_solid_loader。

我遇到了这个: Is it possible to write a template to check for a function's existence? 但它似乎有点不同,因为我没有检查方法,而是检查具有特定参数类型的函数。

现在可以吗?

2 个答案:

答案 0 :(得分:5)

您可以为extended_solid_loader提供一个提供默认实现的函数模板,而想要使用默认实现以外的其他用户的用户只需专门化。

template<class T>
void extended_solid_loader(T & ret, SomeClass & obj) {
    // default implementation here
}

template<>
void extended_solid_loader<MooClass>(MooClass & ret, SomeClass & obj) {
    // special implementation for MooClass here
}

答案 1 :(得分:2)

你实际上不需要做任何特别特别的事情。只需确保模板可以使用该函数的一个版本,然后让ADL完成脏工作。看看这个例子:

#include <iostream>

namespace bob {

  struct X {};

  void f(X const&) { std::cout << "bob::f\n"; }
}

namespace ed {

  template < typename T >
  void f(T const&) { std::cout << "ed::f\n"; }

  template < typename T >
  struct test
  {
    void doit() // not called f and no other member so named.
    { f(T()); }
  };

}

int main()
{
  ed::test<int> test1;
  ed::test<bob::X> test2;

  test1.doit();
  test2.doit();

  std::cin.get();
}

也没有名称空间的东西(非模板有首选项)。我只是用它来表明ADL会在你做的时候把它拿起来。


你原来的问题很有意思。找到了在C ++ 0x中实现它的方法:

template < typename T >
struct fun_exists
{
  typedef char (&yes) [1];
  typedef char (&no)  [2];

  template < typename U >
  static yes check(decltype(f(U()))*);

  template < typename U >
  static no check(...);

  enum { value = sizeof(check<T>(0)) == sizeof(yes) };
};

void f(double const&) {}

struct test {};

#include <iostream>
int main()
{
  std::cout << fun_exists<double>::value << std::endl;
  std::cout << fun_exists<test>::value << std::endl;

  std::cin.get();
}