如何确定一个函数参数的类型给定的参数传递给它的类型? [英] How to determine the type of a function parameter given the type of argument passed to it?

查看:165
本文介绍了如何确定一个函数参数的类型给定的参数传递给它的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个类型trait,它将报告函子的 operator()参数的类型,给定函子的类型和传递给它的参数的类型。基本上,我需要确定参数将被转换为什么类型,当传递给函子。为简单起见,让我们假设我只对一个(可能模板的,可能重载的) operator()感兴趣。不幸的是,我只能使用c ++ 03。可以做吗?如果不是,怎么样c ++ 11?

I need a type trait which will report the type of a functor's operator() parameter given the type of the functor and the type of an argument passed to it. Basically, I need to determine precisely what type the argument will be converted to when passing it to the functor. For simplicity, let's assume that I'm only interested in a (potentially templated, potentially overloaded) operator() with a single argument. Unfortunately, I'm limited to c++03. Can it be done? If not, how about c++11?

这里有一个例子:

#include <cassert>
#include <type_traits>

template<typename Functor, typename Argument>
  struct parameter_type
{
  // what goes here?
  typedef ... type;
};

struct takes_float_cref
{
  void operator()(const float &);
};

int main()
{
  // when calling takes_float_cref::operator() with an int,
  // i'd expect a conversion to const float &
  assert(std::is_same(parameter_type<takes_float_cref, int>::type, const float &>::value);

  return 0;
}

A 相关问题(它的答案没有给我我需要的)给出了需要这样一个特征的上下文我已经进行了进一步的单元测试 ideone

A related question (whose answer doesn't give me quite what I need) gives the context for needing such a trait. I've put further unit tests on ideone.

推荐答案

恐怕

TL; DR :单元测试 fail (grrr gcc)。

TL;DR: unit test fail (grrr gcc).

你的问题的一般情况是这个函子:

The general case of your question is this functor:

struct Functor {
  template <typename T>
  typename std::enable_if<std::is_integral<T>::value>::type
  operator()(T t) const;

  void operator(double d) const;
};

它结合了两个主要问题:

It combines the two main issues here:


  1. 如果有过载,则& F :: operator()需要 static_cast
  2. 模板(以及表达它们的任意条件)不能成功地表示为 typedef s

  1. If there is an overload, then taking &F::operator() requires a static_cast to a given type to disambiguate which overload should be used
  2. Templates (and arbitrary conditions to express them) cannot be succintly expressed as typedefs

因此,客户( Functor 为您提供额外的钩子,如果你真的希望得到这种类型。没有 decltype 我看不到如何获取它(注意, gcc 提供 typeof

Therefore, the client (Functor here) need to provide additional hooks for you if you truly wish to get this type. And without decltype I don't see how to get it (note, gcc provides typeof as an extension in C++03).

让客户给我们提示:

// 1. Make use of the return value:
struct Functor {
  template <typename T>
  typename std::enable_if<std::is_integral<T>::value, T>::type
  operator()(T t) const;

  double operator(double d) const;
};

// 2. Double up the work (but leave the return value as is)
struct Functor {
  template <typename T>
  static typename std::enable_if<std::is_integral<T>::value, T>::type Select(T);

  static double Select(T);

  template <typename T>
  typename std::enable_if<std::is_integral<T>::value>::type
  operator()(T t) const;

  void operator(double d) const;
};

让我们假设我们继续使用第二种情况p>

Let's say we go for the second case (leaving the return value free for another use).

template <typename F, typename T>
struct parameter {
  static T t;
  typedef decltype(F::Select(t)) type;
};

在C ++ 03中,替换 decltype typeof 与gcc。

In C++03, replace decltype by typeof with gcc.

我没有办法放弃 decltype sizeof 确实提供了一个未经评估的上下文,但它似乎在这里不太有用。

I don't see a way to forego decltype. sizeof does provides an unevaluated context but it does not seem to help much here.

Unit测试在这里

不幸的是, ,并且 float& 被减少到 float (和任何其他引用真的),错误仍然是 decltype ,所以它只是一个错误的实现:/ Clang 3.0对C ++ 11版本没有问题( decltype ), typeof 我想。

Unfortunately, there is a gcc bug it seems with the references, and float& gets reduced to float (and any other reference really), the bug remains with decltype so it's just a buggy implementation :/ Clang 3.0 has no problem with the C++11 version (decltype) but does not implement typeof I think.

这可以通过要求客户端使用 ref< float> 类,然后解开它。只是有点更多的负担...

This can be worked around by requiring the client to use a ref<float> class instead, and then unwrapping it. Just a bit more burden...

这篇关于如何确定一个函数参数的类型给定的参数传递给它的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆