【问题标题】:decltype of function parameter [duplicate]函数参数的decltype [重复]
【发布时间】:2017-09-17 12:11:48
【问题描述】:

是否可以推断出函数参数的类型?例如,如果我有:

void foo(int a);

我想推导出int的类型为foo的第一个参数的类型。可能的用途是:

foo( static_cast< decltype(/* ??? foo's first param ??? */) >(value) );

this related question中,answers利用了具有相同类型的成员进行推导,因此它不直接推导函数参数类型。

【问题讨论】:

  • Related,不确定是否完全重复,所以没有这样标记。
  • 寻找功能特征。
  • 它似乎是重复的,虽然这里的答案更好。

标签: c++ c++11 templates type-deduction


【解决方案1】:

是否可以推导出函数参数的类型?

当然。

以类型特征为例 (argType)

template <typename>
struct argType;

template <typename R, typename A>
struct argType<R(A)>
 { using type = A; };


void foo(int a)
 { }

int main()
 {
   long value = 1L;

   foo( static_cast<typename argType<decltype(foo)>::type>(value) );
 }

如果您对更通用的解决方案感兴趣,以下示例展示了如何创建和使用类型特征来检测返回类型或第 n 个参数类型

#include <string>

template <std::size_t N, typename T0, typename ... Ts>
struct typeN
 { using type = typename typeN<N-1U, Ts...>::type; };

template <typename T0, typename ... Ts>
struct typeN<0U, T0, Ts...>
 { using type = T0; };

template <std::size_t, typename>
struct argN;

template <std::size_t N, typename R, typename ... As>
struct argN<N, R(As...)>
 { using type = typename typeN<N, As...>::type; };

template <typename>
struct returnType;

template <typename R, typename ... As>
struct returnType<R(As...)>
 { using type = R; };

long bar (int a, std::string const &)
 { return a; }

int main()
 {
   long         valI = 1L;
   char const * valS = "abc";

   bar( static_cast<typename argN<0U, decltype(bar)>::type>(valI),
        static_cast<typename argN<1U, decltype(bar)>::type>(valS) );

   static_assert(
      std::is_same<long,
                   typename returnType<decltype(bar)>::type>::value, "!");
 }

【讨论】:

  • @NoSenseEtAl - 是的,但 lambdas 不是函数。当您有一个可转换为函数指针的 lambda 时,您可以使用 decltype(+baz),(其中 baz 是可转换的 lambda),但您必须修改 returnTypeargN 才能工作(也是?)带有函数指针。
【解决方案2】:

the answer by @max66 的一个稍微概括的版本:

template <typename> struct FirstArgument;

template <typename R, typename A, typename... Args>
struct FirstArgument<R(A, Args...)>
{
   using type = A;
};

template <typename T>
using first_agument_t = typename FirstArgument<T>::type;

void foo(int a){ }

void bar(int a, double b){ }

int main()
{
   long value = 1L;
   foo(static_cast<first_agument_t<decltype(foo)>>(value) );
   bar(static_cast<first_agument_t<decltype(bar)>>(value), 0);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多