具有功能定义:
void f(int) { }
我想定义:
int a;
但如果函数定义更改为:
void f(double) { }
变量定义必须变为:
double a;
也就是说,“a”的类型必须与“f”函数的第一个参数相同。 我需要以下内容:
decltype_of_argument<f, 0> a;
是否可以在C ++中使用?
答案 0 :(得分:21)
您可以通过模板元编程获取类型:
template <class F> struct ArgType;
template <class R, class T>
struct ArgType<R(*)(T)> {
typedef T type;
};
void f(int) {}
#include <type_traits>
#include <iostream>
int main() {
// To prove
std::cout << std::is_same< ArgType<decltype(&f)>::type, int >::value << '\n';
// To use
ArgType<decltype(&f)>::type a;
}
根据您想要使用它的位置,您需要将此litte模板专门用于其他可调用实体,例如成员函数poitners,具有更多参数的函数,仿函数等。在Boost库中有更多复杂的方法,见例如https://stackoverflow.com/a/15645459/1838266
警告:所有这些实用程序仅在函数/ callable的名称明确映射到单个函数签名时才起作用。如果函数超载或者仿函数有多个operator()
,则必须通过显式转换到正确的签名来选择正确的函数/运算符,这使得通过模板找出部分签名非常无用。这也适用于模板,尽管获得明确特殊化的可调用的签名可能仍然有用,例如:
template <unsigned N, class F> struct ArgType; //somewhat more sophisitcated
template <class T> void f(int, T);
ArgType<0, decltype(&f<double>)> //int - ArgType has it's use here
ArgType<1, decltype(&f<double>)> //double - here it's useless...
答案 1 :(得分:3)
使用模板?
template< typename T >
void f( T )
{
T a;
}
答案 2 :(得分:3)
这取决于你想做什么,应该使用哪个变量。如果它在函数中,模板可能是一个不错的选择:
template<typename T>
void foo(T ) {
T a;
}
或者,如果您不在函数范围内并且要求真正了解这一点,则可以使用Boost.TypeTraits,即function_traits<void (int)>::arg1_type
将int
答案 3 :(得分:2)
其中一种方法是使用typedef作为函数参数的类型。例如
typedef int TParm;
void f( TParm );
TParm a;
您可以为该类型选择任何名称。例如parm_t
等等。重要的是不会发生名称冲突。
在这种情况下,如果要更改参数类型,则只需要更改typedef。
或者,如果您的编译器支持别名,您也可以编写
using TParm = int;
void f( TParm );
TParm a;
此外,您可以将函数包装在命名空间或类中。:)例如
struct IFunction
{
typedef int parm_t;
static void f( parm_t = parm_t() ) {}
};
//...
IFunction::parm_t a;
IFunction::f( a );
答案 4 :(得分:0)
如何制作模板功能?
template <typename T>
void f(T t);