【问题标题】:is there a cleaner way of passing variadic data?有没有更简洁的方法来传递可变参数数据?
【发布时间】:2019-02-15 19:59:01
【问题描述】:

如何以更简洁的方式将可变参数数据从一个函数传递到另一个函数?

演示代码:

void * variadic_data = nullptr;

void send_1(){
   if(sendto(...)){
       variadic_data = static_cast<void *>(new int(123)); // from here
   }
}

void send_2(){
   if(sendto(...)){
       variadic_data = static_cast<void *>(new std::string("test"));
   }
}

void task(){
    ...
    do {
        i_result =  recv(...);
        std::string message(buff, i_result);
        if(message == ...){
            int * int_1 = static_cast<int *>(variadic_data); // to here
            ...
            delete int_1 ;
        } else if (message == ...) {
            std::string * str_1 = static_cast<std::string *>(variadic_data);
            ...
            delete str_1;
        }
    } while(i_result != 0 && i_result != SOCKET_ERROR);
}

我有额外的recv线程和少数其他线程sendto函数,许多sendto有不同的局部变量,在recv线程响应后需要。我认为在额外的线程中阻塞 recv 是常见的方式。这只是糟糕的应用程序设计吗?我应该创建消息管理器并在 sendto 之后立即选择吗?

【问题讨论】:

  • 为什么variadic_data有多种内容?为什么不分开变量?为什么是全球性的?为什么std::variadic 不起作用?为什么这看起来像一个消息泵,其中额外的数据存储在全局而不是消息中?
  • @MooingDuck variadic_data 有多种类型的内容,因为我尽量避免为每个发送本地类型使用单独的变量。它是全局的,因为每个函数都可以访问。 std::variadic 你的意思是可变参数?它们不起作用,因为任务已经在运行。当服务器根本不需要它们时,为什么要在消息中发送额外的数据?
  • 对不起,我的意思是std::variant。但是你不应该有全局变量。一般来说,可变全局变量几乎总是一个坏主意,并且会导致错误。

标签: c++ multithreading networking


【解决方案1】:

使用std::variant,例如:

std::variant<int, std::string> variadic_data;

...

variadic_data = 123;

...

variadic_data = std::string("test");

... 

if (message == ...) {
    int int_1 = std::get<int>(variadic_data);
    ...
}
else if (message == ...) {
    std::string str_1 = std::get<std::string>(variadic_data);
    ...
}

或者,改用std::any,例如:

std::any variadic_data;

...

variadic_data = 123;
// or variadic_data = std::make_any<int>(123);

...

variadic_data = std::string("test");
// or variadic_data = std::make_any<std::string>("test");

... 

if (message == ...) {
    int int_1 = std::any_cast<int>(variadic_data);
    ...
}
else if (message == ...) {
    std::string str_1 = std::any_cast<std::string>(variadic_data);
    ...
}

【讨论】:

  • 我同意这一点(但我最初将问题误读为定义 C 风格的可变参数列表)
  • 这看起来比std::any 更干净,但我会使用它,因为我不必明确指定特定类型(有很多)
【解决方案2】:

是的,你通常可以使用模板函数。

在 c++17(或使用 Boost)中,您可以使用 std::any

在您的特定情况下,我会使用 std::function 对处理程序进行类型擦除。

【讨论】:

  • 我打算做一个例子,但事实证明我并不真正理解你的代码。所以,也许我的最后一行也持保留态​​度。
猜你喜欢
  • 2021-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多