是否可以捕获形式参数的类型,只包含函数名和实际参数?
我需要类似于decltype的东西,但它应该返回函数类型而不是函数的返回类型。
我找到了使用C ++ 11的半解决方案。如果函数没有重载,您可以使用decltype来获取签名,仅指定函数名称和模板参数(如果有),但不指定实际参数:
template<class F>
struct my_function_traits;
// function pointer
template<class R, class Arg>
struct my_function_traits<R(*)(Arg)> : public my_function_traits<R(Arg)>
{
typedef Arg type;
};
template<class R, class Arg1>
struct my_function_traits<R(Arg1)>
{
typedef Arg1 type;
};
namespace itk
{
template <typename PixelType, unsigned Dimension>
class Image;
}
template <typename TPixel, unsigned VDimension>
void func2(itk::Image<TPixel, VDimension>* image) {}
int main()
{
typedef my_function_traits< decltype(func2<int, 2>) > Traits;
Traits::type var = 0;
return 0;
}
这很好用,但如果我添加其他功能,decltype将无法解析该类型:
template <typename TPixel, unsigned VDimension>
void func2(const itk::Image<TPixel, VDimension>* image, int i) {}
有什么意义,因为函数名称不明确,两个版本都有相同的模板参数。但是编译器必须能够从实际参数的静态类型中找出正确的函数。问题是,只要我指定它们,decltype就会返回表达式的类型,即函数的返回类型。
itk::Image<int, 3>* image;
int a = 3;
...
typedef my_function_traits< decltype(func2<int, 2>(image, 3)) > Traits;
我的主要目标是检查第一个参数的常量。
感谢您的帮助!
答案 0 :(得分:3)
假设您不知道第一个指针的常量,并且您知道连续的参数类型,则可以使用以下内容:
template <typename T, typename ...Ts>
struct is_first_arg_const_ptr
{
template <typename Ret>
static std::false_type
is_const(Ret (&f)(T*, Ts...));
template <typename Ret>
static std::true_type
is_const(Ret (&f)(const T*, Ts...));
// And for methods
template <typename Ret, typename C>
static std::false_type
is_const (Ret (C::*) (T*, Ts...)) /* const volatile & && */;
template <typename Ret, typename C>
static std::true_type
is_const (Ret (C::*) (const T*, Ts...)) /* const volatile & && */;
// .. complete for all combinations of cv_qualifier and ref
};
现在,正确选择过载没有歧义。
对于宏,您可以执行以下操作:
template <typename T, typename ...Ts>
constexpr
auto make_is_first_arg_const_ptr(T&& t, Ts&&...)
-> is_first_arg_const_ptr<
typename std::decay<decltype(*t)>::type,
typename std::decay<Ts>::type...
>;
#define IS_FIRST_ARG_CONST_PTR(Name, ...) \
(decltype(make_is_first_arg_const_ptr(__VA_ARGS__).is_const(Name))::value)
然后将其用作
static_assert(!IS_FIRST_ARG_CONST_PTR(func2, image), "");
static_assert(IS_FIRST_ARG_CONST_PTR(func2, image, a), "");
static_assert(IS_FIRST_ARG_CONST_PTR(&MyClass::func2, image, a), "");
请注意,宏不适用于func
的某些原型,因为我从参数中推断出类型,但在这种情况下你会得到一个编译错误(你可以用更合适的特性改变std::decay
符合你的需要)。
答案 1 :(得分:1)