<i id='TuPAt'><tr id='TuPAt'><dt id='TuPAt'><q id='TuPAt'><span id='TuPAt'><b id='TuPAt'><form id='TuPAt'><ins id='TuPAt'></ins><ul id='TuPAt'></ul><sub id='TuPAt'></sub></form><legend id='TuPAt'></legend><bdo id='TuPAt'><pre id='TuPAt'><center id='TuPAt'></center></pre></bdo></b><th id='TuPAt'></th></span></q></dt></tr></i><div id='TuPAt'><tfoot id='TuPAt'></tfoot><dl id='TuPAt'><fieldset id='TuPAt'></fieldset></dl></div>
  • <small id='TuPAt'></small><noframes id='TuPAt'>

    • <bdo id='TuPAt'></bdo><ul id='TuPAt'></ul>

        <tfoot id='TuPAt'></tfoot>
      1. <legend id='TuPAt'><style id='TuPAt'><dir id='TuPAt'><q id='TuPAt'></q></dir></style></legend>

        使用从字符串中提取的参数调用函数

        时间:2023-10-17
          <tbody id='mhwNt'></tbody>
        <tfoot id='mhwNt'></tfoot>

          <i id='mhwNt'><tr id='mhwNt'><dt id='mhwNt'><q id='mhwNt'><span id='mhwNt'><b id='mhwNt'><form id='mhwNt'><ins id='mhwNt'></ins><ul id='mhwNt'></ul><sub id='mhwNt'></sub></form><legend id='mhwNt'></legend><bdo id='mhwNt'><pre id='mhwNt'><center id='mhwNt'></center></pre></bdo></b><th id='mhwNt'></th></span></q></dt></tr></i><div id='mhwNt'><tfoot id='mhwNt'></tfoot><dl id='mhwNt'><fieldset id='mhwNt'></fieldset></dl></div>

          1. <legend id='mhwNt'><style id='mhwNt'><dir id='mhwNt'><q id='mhwNt'></q></dir></style></legend>

                • <bdo id='mhwNt'></bdo><ul id='mhwNt'></ul>
                • <small id='mhwNt'></small><noframes id='mhwNt'>

                  本文介绍了使用从字符串中提取的参数调用函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在研究以下问题:

                  我得到的字符串格式如下:

                  I get strings that are formatted like this:

                  functionname_parameter1_parameter2_parameter3
                  otherfunctionname_parameter1_parameter2
                  .
                  .
                  .
                  

                  我想用给定的参数调用函数.假设我有一个功能测试:

                  and i would like to call the function with the given parameters. So let's say i have a function test:

                  void test(int x, float y, std::string z) {}
                  

                  然后我收到一条消息:

                  test_5_2.0_abc
                  

                  然后我希望像这样自动调用函数测试:

                  then i would like the function test to be automatically invoked like this:

                  test(5, 2.0, "abc");
                  

                  关于如何在 C++ 中实现这一点,您有什么提示吗?

                  Do you have any hints on how to accomplish this in C++?

                  推荐答案

                  更新: 更新了 stream_function 以修复评论中提到的参数评估顺序问题@Nawaz,并且还删除了 std::function 以提高效率.请注意,评估顺序修复仅适用于 Clang,因为 GCC 不遵循此处的标准. 可以找到带有手动顺序执行的 GCC 示例 这里.

                  Update: Updated stream_function to fix the argument-evaluation-order problem @Nawaz mentioned in the comments, and also removed the std::function for improved efficiency. Note that the evaluation-order fix only works for Clang, as GCC doesn't follow the standard here. An example for GCC, with manual order-enforcement, can be found here.

                  这通常不是那么容易实现.我曾经围绕 std::function 编写了一个小包装类,用于从 std::istream 中提取参数.下面是一个使用 C++11 的例子:

                  This is generally not that easy to accomplish. I wrote a little wrapper class around std::function once that extracts the arguments from a std::istream. Here's an example using C++11:

                  #include <map>
                  #include <string>
                  #include <iostream>
                  #include <sstream>
                  #include <functional>
                  #include <stdexcept>
                  #include <type_traits>
                  
                  // for proper evaluation of the stream extraction to the arguments
                  template<class R>
                  struct invoker{
                    R result;
                    template<class F, class... Args>
                    invoker(F&& f, Args&&... args)
                      : result(f(std::forward<Args>(args)...)) {}
                  };
                  
                  template<>
                  struct invoker<void>{
                    template<class F, class... Args>
                    invoker(F&& f, Args&&... args)
                    { f(std::forward<Args>(args)...); }
                  };
                  
                  template<class F, class Sig>
                  struct stream_function_;
                  
                  template<class F, class R, class... Args>
                  struct stream_function_<F, R(Args...)>{
                    stream_function_(F f)
                      : _f(f) {}
                  
                    void operator()(std::istream& args, std::string* out_opt) const{
                      call(args, out_opt, std::is_void<R>());
                    }
                  
                  private:  
                    template<class T>
                    static T get(std::istream& args){
                      T t; // must be default constructible
                      if(!(args >> t)){
                        args.clear();
                        throw std::invalid_argument("invalid argument to stream_function");
                      }
                      return t;
                    }
                  
                    // void return
                    void call(std::istream& args, std::string*, std::true_type) const{
                      invoker<void>{_f, get<Args>(args)...};
                    }
                  
                    // non-void return
                    void call(std::istream& args, std::string* out_opt, std::false_type) const{
                      if(!out_opt) // no return wanted, redirect
                        return call(args, nullptr, std::true_type());
                  
                      std::stringstream conv;
                      if(!(conv << invoker<R>{_f, get<Args>(args)...}.result))
                        throw std::runtime_error("bad return in stream_function");
                      *out_opt = conv.str();
                    }
                  
                    F _f;
                  };
                  
                  template<class Sig, class F>
                  stream_function_<F, Sig> stream_function(F f){ return {f}; }
                  
                  typedef std::function<void(std::istream&, std::string*)> func_type;
                  typedef std::map<std::string, func_type> dict_type;
                  
                  void print(){
                    std::cout << "print()
                  ";
                  }
                  
                  int add(int a, int b){
                    return a + b;
                  }
                  
                  int sub(int a, int b){
                    return a - b;
                  }
                  
                  int main(){
                    dict_type func_dict;
                    func_dict["print"] = stream_function<void()>(print);
                    func_dict["add"] = stream_function<int(int,int)>(add);
                    func_dict["sub"] = stream_function<int(int,int)>(sub);
                  
                    for(;;){
                      std::cout << "Which function should be called?
                  ";
                      std::string tmp;
                      std::cin >> tmp;
                      auto it = func_dict.find(tmp);
                      if(it == func_dict.end()){
                        std::cout << "Invalid function '" << tmp << "'
                  ";
                        continue;
                      }
                      tmp.clear();
                      try{
                        it->second(std::cin, &tmp);
                      }catch(std::exception const& e){
                        std::cout << "Error: '" << e.what() << "'
                  ";
                        std::cin.ignore();
                        continue;
                      }
                      std::cout << "Result: " << (tmp.empty()? "none" : tmp) << '
                  ';
                    }
                  }
                  

                  在 Clang 3.3 下编译并按预期工作(小型现场示例).

                  Compiles under Clang 3.3 and works as expected (small live example).

                  Which function should be called?
                  a
                  Invalid function 'a'
                  Which function should be called?
                  add
                  2
                  d
                  Error: 'invalid argument to stream_function'
                  Which function should be called?
                  add
                  2
                  3
                  Result: 5
                  Which function should be called?
                  add 2 6
                  Result: 8
                  Which function should be called?
                  add 2   
                  6
                  Result: 8
                  Which function should be called?
                  sub 8 2
                  Result: 6
                  

                  再次一起破解那个课程很有趣,希望你喜欢.请注意,您需要稍微修改代码以适用于您的示例,因为 C++ IOstreams 将空格作为分隔符,因此您需要用空格替换消息中的所有下划线.不过应该很容易做到,之后只需从您的消息中构造一个 std::istringstream :

                  It was fun to hack that class together again, hope you enjoy. Note that you need to modify the code a little to work for your example, since C++ IOstreams have whitespace as delimiter, so you'd need to replace all underscores in your message with spaces. Should be easy to do though, after that just construct a std::istringstream from your message:

                  std::istringstream input(message_without_underscores);
                  // call and pass 'input'
                  

                  这篇关于使用从字符串中提取的参数调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:c-ares 为 DNS 解析指定网络接口 下一篇:如何在函数和成员函数上编写包装器,在包装函数之前和之后执行一些代码?

                  相关文章

                  1. <legend id='BfevM'><style id='BfevM'><dir id='BfevM'><q id='BfevM'></q></dir></style></legend>

                    <small id='BfevM'></small><noframes id='BfevM'>

                      <bdo id='BfevM'></bdo><ul id='BfevM'></ul>
                    <tfoot id='BfevM'></tfoot>

                  2. <i id='BfevM'><tr id='BfevM'><dt id='BfevM'><q id='BfevM'><span id='BfevM'><b id='BfevM'><form id='BfevM'><ins id='BfevM'></ins><ul id='BfevM'></ul><sub id='BfevM'></sub></form><legend id='BfevM'></legend><bdo id='BfevM'><pre id='BfevM'><center id='BfevM'></center></pre></bdo></b><th id='BfevM'></th></span></q></dt></tr></i><div id='BfevM'><tfoot id='BfevM'></tfoot><dl id='BfevM'><fieldset id='BfevM'></fieldset></dl></div>