Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从实际参数捕获函数参数类型_C++_Templates_C++11_Template Meta Programming_Decltype - Fatal编程技术网

C++ 从实际参数捕获函数参数类型

C++ 从实际参数捕获函数参数类型,c++,templates,c++11,template-meta-programming,decltype,C++,Templates,C++11,Template Meta Programming,Decltype,是否可以捕获只有函数名和实际参数的形式参数的类型 我需要类似于decltype的东西,但它应该返回函数类型,而不是函数的返回类型 itk::Image<int, 3>* image; int a = 3; ... typedef my_function_traits< decltype(func2<int, 2>(image, 3)) > Traits; 我用C++11找到了一半的解决方案。如果函数未重载,则可以使用decltype获取签名,

是否可以捕获只有函数名和实际参数的形式参数的类型

我需要类似于decltype的东西,但它应该返回函数类型,而不是函数的返回类型

  itk::Image<int, 3>* image;
  int a = 3;
  ...
  typedef my_function_traits< decltype(func2<int, 2>(image, 3)) > Traits;
我用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;
我的主要目标是检查第一个论点的稳定性


谢谢你的帮助

Boost就是这样做的。看看boost的功能特点:


Boost做到了这一点。看看boost的功能特点:


假设您不知道第一个指针的常量,并且知道连续参数类型,则可以使用以下方法:

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
};

请注意,当我从参数推断类型时,宏将不适用于func的某些原型,但在这种情况下,您将得到一个编译错误。您可以通过更合适的特征更改std::decay以满足您的需要。

假设您不知道第一个指针的常量,并且知道连续参数的类型,您可以使用以下选项:

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
};

请注意,当我从参数推断类型时,宏将不适用于func的某些原型,但在这种情况下,您将得到一个编译错误。您可以通过更合适的traits来更改std::decay以满足您的需要。

OP的问题似乎是在函数之间选择正确的重载,而不是函数的traits部分。我还没有用boost解决这个问题。我也尝试了函数traits和boost::bind。似乎OP的问题是在函数之间选择正确的重载,而不是函数的特性部分。我还没有用boost解决这个问题。我也尝试了函数traits和boost::bind。不幸的是,我不知道连续参数的类型。我只知道第一个参数的类型,它是指向常量图像还是非常量图像的指针。那么您想如何在func2const图像*、int和func2image*之间进行选择?与gcc 4.9一起使用,clang 3.4 clang生成警告,这里我使用g++tdm-2 4.8。1@espakm:我在结尾未注释代码时收到了您的错误。这是因为宏不喜欢参数中的逗号,所以MACROfun3,&d看到3个参数,而您期望看到2个。解决方法是使用额外的括号,因此使用MACROfun3,&d。@espakm:对于类参数,您可以创建另一个帮助器类模板结构。首先为类创建is_\u arg\u const\u ptr\u,然后为类创建is_const\u ptr\u,这将不会是模板,这将解决您的问题。不幸的是,我不知道后续参数的类型。我只知道第一个参数的类型,它是指向常量图像还是非常量图像的指针。那么您想如何在func2const图像*、int和func2image*之间进行选择?与gcc 4.9一起使用,clang 3.4 clang生成警告,这里我使用g++tdm-2 4.8。1@espakm:我在结尾未注释代码时收到了您的错误。这是因为宏不喜欢参数中的逗号,所以MACROfun3,&d看到3个参数,而您期望看到2个。解决方法是使用额外的括号,因此使用MACROfun3,&d。@espakm:对于类参数,您可以创建另一个帮助器类模板结构。首先为类创建is_\u arg\u const\u ptr\u,然后为类创建is_const,这将解决您的问题。