c++ 什么是std::function::argument_type的替代?

ljo96ir5  于 2023-06-25  发布在  其他
关注(0)|答案(4)|浏览(191)

根据cppreference.com所有以下三个:argument_typefirst_argument_typesecond_argument_type在C17中被弃用,在C20中被删除。
这些成员类型的标准库替换是什么?我的意思是,我可以编写自己的类型特征,但我怀疑在标准库中没有适当的替代品的情况下,某些东西会被删除。
例如:

  1. template <typename F>
  2. void call_with_user_input(F f) {
  3. typename F::first_argument_type x; // what to use instead ??
  4. std::cin >> x;
  5. f(x);
  6. }
mfpqipee

mfpqipee1#

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

  1. template <typename Ret, typename Arg>
  2. void call_with_user_input(std::function<Ret(Arg)> f) {
  3. Arg x;
  4. std::cin >> x;
  5. f(x);
  6. }

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

piv4azn7

piv4azn72#

据我所知,他们将被删除,仅此而已。我发现提案here
first_argument_typesecond_argument_type相关:
自适应函数绑定在C17中是一个很强的删除候选者,但被保留只是因为没有足够的替代品供一元/二元否定符的用户迁移。该特性std::not_fn被添加到C17中以允许迁移路径。
检查c++17的std::not_fn发现:
注意,自适应函数协议在最初设计时不再起作用,这是由于添加了新的语言特性和库,例如lambda表达式、“菱形”函子等等。这并不是因为缺乏努力,而仅仅是因为不可能为这些类型中的某些类型(例如多态lambda对象)拥有一组唯一的typedef。然而,我们确实为在库中的其他地方保留支持付出了代价,因为在几个组件中有笨拙的条件定义成员typedef,例如std::function Package 一个只有一个或两个参数的函数类型,或者类似地std::reference_wrapper用于只有一个或两个参数的函数引用。
这意味着它们将被删除。
first_argument_typesecond_argument_type的问题之一似乎是因为polymorphic lambda objects
同样如注解中所指出的,任何可以传递给std::variant<...>::visit的具有多个operator()的东西都有first_argument_type的问题

a0zr77ik

a0zr77ik3#

一种方法是使用boost::function_types

  1. #include <boost/function_types/parameter_types.hpp>
  2. #include <boost/mpl/at.hpp>
  3. template <typename F>
  4. void call_with_user_input(F f) {
  5. using FnType = decltype(&F::operator());
  6. using FirstArgType = typename boost::mpl::at_c<boost::function_types::parameter_types<FnType>, 0>::type;
  7. FirstArgType x;
  8. std::cin >> x;
  9. f(x);
  10. }
798qvoo8

798qvoo84#

不幸的是,我认为这必须使用标准的SFINAE type_trait实现技术来完成。下面是一个first_argument_type的替换示例,扩展到提取所有模板参数或任何特定的模板参数应该相当简单。
我怀疑在大多数情况下,你会想要衰减模板类型,但是我不知道标准实现是否衰减了它。

  1. #include <functional>
  2. #include <tuple>
  3. template<typename... T>
  4. struct extract_first_arg_type;
  5. template<typename RetType, typename... ValTypes>
  6. struct extract_first_arg_type<std::function<RetType(ValTypes...)>> {
  7. using type = std::decay_t<std::tuple_element_t<0, std::tuple<ValTypes...>>>;
  8. };
  9. std::function<void(int, double)> f = [](int k, double d) {};
  10. static_assert(std::is_same_v<extract_first_arg_type<decltype(f)>::type, int>, "");
  11. static_assert(!std::is_same_v<extract_first_arg_type<decltype(f)>::type, double>, "");

godbolt link

展开查看全部

相关问题