【问题标题】:What is the replacement for std::function::argument_type?std::function::argument_type 的替代品是什么?
【发布时间】:2018-09-28 13:25:43
【问题描述】:

根据cppreference.com,所有以下三个:argument_typefirst_argument_typesecond_argument_type 在 C++17 中已弃用并在 C++20 中删除。

这些成员类型的标准库替代品是什么?我的意思是我可以编写自己的类型特征,但我怀疑在标准库中没有适当替换的情况下会删除某些内容。

举个例子:

template <typename F> 
void call_with_user_input(F f) {
    typename F::first_argument_type x;  // what to use instead ??
    std::cin >> x;
    f(x);
}

【问题讨论】:

  • 您可以为此创建一个特征。作为奖励,您的方法也适用于 lambda。
  • @NathanOliver 最佳答案说“[...] 你无法获得它的参数类型”,这并不是argument_type 的真正替代品;)
  • @user463035818 你想让F 成为任何可调用类型还是仍然是std::function?我问是因为first_argument_type 只存在于std::function。 lambda、函数和大多数仿函数都没有。而且,就像第一个答案所示,我认为这通常是不可能的,因为 operator() 可以重载。
  • 所以template &lt;typename Ret, typename FirstArg&gt; void call_with_user_input(std::function&lt;Ret(FirstArg)&gt; f) :-) 因为奖金可以处理的不仅仅是前两个参数。

标签: c++ function


【解决方案1】:

可以通过引入模板参数来获取类型

template <typename Ret, typename Arg> 
void call_with_user_input(std::function<Ret(Arg)> f) {
    Arg x;
    std::cin >> x;
    f(x);
}

将参数类型作为模板参数提供给您。作为奖励,如果需要,您还可以获得返回类型。

【讨论】:

  • 实际上现在我想知道为什么首先会有first_argument。似乎删除它并没有真正产生重大后果
  • @user463035818 许多旧的 C++03 机制都需要它,这些机制已被删除。查看更多信息:stackoverflow.com/questions/35907454/…
  • “事实上,这些 typedef 比没用还糟糕……”这让我最终信服。我被误导认为他们需要一些东西
  • @user463035818 我认为将arguments_type 类型作为Arg 的元组会很有用...引入更多模板参数有时会很麻烦,因为有已经是result_type
【解决方案2】:

据我了解,它们将被删除,仅此而已。 我找到了提案here

first_argument_typesecond_argument_type相关:

自适应函数绑定是 C++17 中删除的有力候选者,但保留只是因为没有足够的替代品可供一元/二元否定符的用户迁移到。该特性 std::not_fn 被添加到 C++17 以允许迁移路径,

检查std::not_fn for c++17 我发现:

请注意,由于添加了新的语言特性和库,例如 lambda 表达式、“菱形”仿函数等,自适应函数协议不再像最初设计时那样正常工作。这并不是因为缺乏努力,而只是因为不可能为其中一些类型(例如多态 lambda 对象)拥有一组唯一的 typedef。然而,我们确实为在库中的其他地方保留支持付出了代价,因为在几个组件中笨拙的条件定义成员 typedef,例如 std::function 用一个或两个参数包装一个函数类型,或者类似地用于 std:: reference_wrapper 用于仅包含一个或两个参数的函数引用。

这意味着它们将被删除。

first_argument_typesecond_argument_type 的问题之一似乎是因为polymorphic lambda objects

正如 cmets 中所指出的,任何可以传递给 std::variant&lt;...&gt;::visit 的具有多个 operator() 的东西都存在 first_argument_type 的问题

【讨论】:

  • 任何具有多个 operator()s 的东西,而不仅仅是多态 lambda。哪些是您可以有效传递给std::variant&lt;...&gt;::visit任何内容
【解决方案3】:

一种方法是使用boost::function_types:

#include <boost/function_types/parameter_types.hpp>
#include <boost/mpl/at.hpp>

template <typename F> 
void call_with_user_input(F f) {
    using FnType = decltype(&F::operator());
    using FirstArgType = typename boost::mpl::at_c<boost::function_types::parameter_types<FnType>, 0>::type;
    FirstArgType x;
    std::cin >> x;
    f(x);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-14
    • 2019-02-22
    • 2011-05-07
    • 2012-04-24
    • 2019-12-03
    • 2010-09-17
    • 2012-03-27
    • 2012-09-30
    相关资源
    最近更新 更多