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

发布于 2024-10-12 14:40:43 字数 517 浏览 5 评论 0原文

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

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

在项目中的多个点上,我有为不同类型定义extend_solid_loader的宏,但现在我希望能够使用默认函数如果尚未为该特定类类型定义extended_solid_loader。

我遇到过这个: 是否可以编写检查函数是否存在的模板? 但它似乎有点不同,因为我不是检查方法,而是检查具有特定参数类型的函数的定义。

现在这可能吗?

So I was looking for ways to check whether a function with a particular argument exists. I have a templated method which relies on an external function (external from the class) to do the job:

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

At multiple points in the project I have macros which define extended_solid_loader for different types, but now I want to be able to use a default function if extended_solid_loader hasn't been defined for that particular class type.

I came across this:
Is it possible to write a template to check for a function's existence?
but it seems a little different, in that I'm not checking for a method, but rather a definition of a function with a particular argument type.

Is this possible right now?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

離殇 2024-10-19 14:40:43

您只需为 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
}

You can just provide a function template for extended_solid_loader providing a default implementation, and users who want to use something other than the default implementation just specialize that.

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
}
甜扑 2024-10-19 14:40:43

您实际上不必做任何特别的事情。只需确保该函数有一个可供模板使用的版本,然后让 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();
}

You don't actually have to do anything particularly special. Just make sure there's a version of that function available to the template and let ADL do the dirty work. Check out this example:

#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();
}

Works without the namespace stuff too (non-templates have preference). I just used that to show that ADL will pick it up when you do.


Your original question was interesting. Found a way to do it in 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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文