如何确定一个函数参数的类型给定的参数传递给它的类型? [英] How to determine the type of a function parameter given the type of argument passed to it?
问题描述
我需要一个类型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:
- 如果有过载,则
& F :: operator()
需要static_cast $ / $>
- 模板(以及表达它们的任意条件)不能成功地表示为
typedef
s
- 模板(以及表达它们的任意条件)不能成功地表示为
- If there is an overload, then taking
&F::operator()
requires astatic_cast
to a given type to disambiguate which overload should be used - Templates (and arbitrary conditions to express them) cannot be succintly expressed as
typedef
s
因此,客户( 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.
不幸的是, ,并且 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屋!