C++ 在知道变量类型之前使用自动定义的变量

C++ Using an auto-defined variable before knowing its type

本文关键字:变量 定义 类型 C++      更新时间:2023-10-16

我目前正在尝试在知道其类型之前使用自动定义的变量。为什么?因为类型取决于程序输入。如果用户选择某个分布,程序将根据该分布输出值。代码如下:

std::default_random_engine random_engine;
auto random;
if(from_dist)
{
    char* dist_name = strtok(distribution_name, "()");
    char* parameters = strtok(nullptr, "()");
    if(strcmp(dist_name, "gaussian") == 0)
    {
        double mean = atof(strtok(parameters, ","));
        double stddev = atof(strtok(nullptr, ","));
        std::normal_distribution<double> normal_distribution(mean, stddev);
        random = std::bind(normal_distribution, random_engine);
    }
        //TODO: Add more...
    else
    {
        std::cerr << "Invalid distribution. Known distributions:" << std::endl;
        std::cerr << "tgaussian(mean,stddev) - gaussian (aka normal) distributions" << std::endl;
        exit(EXIT_FAILURE);
    }
}

但是,C++不允许我以这种方式使用自动变量。是否有任何替代方案允许我使用以下代码片段(稍后执行(,而不必为每个可能的发行版重复它?

while(true) {
        std::string message(OBSERVATION);
        for (int i = 0; i < FEATURE_COUNT; i++)
            message += " " + ((int) random());
        send(sock, message.c_str(), strlen(message.c_str()), 0);
        if (wait_time_ms)
            sleep(wait_time_ms);
}

random的目的(如果我正确阅读了您的代码(是成为一个可调用的对象。

您可以通过使random成为具有正确签名的std::function对象来解决问题:

std::function<double()> random;

编译时必须知道用 auto 声明的变量的类型。如果您真的希望能够使用单个变量名称存储不同类型的值,请查看 std::variant。但是,看起来您甚至不需要使用多种类型。如果我正确理解您的代码,则应将random声明为具有正确签名的std::function对象。

为了使用auto必须初始化变量,以便编译器可以推断出类型。 由于您不确定将拥有哪种类型,因此无法使用它。 不过,由于所有随机生成器都具有double()的形式,因此您可以做的是使用std::function<double()>。 这将允许您在所需的范围内声明random,但允许您为其分配所需的生成器。 那看起来像

std::default_random_engine random_engine;
std::function<double()> random;
if(from_dist)
{
    char* dist_name = strtok(distribution_name, "()");
    char* parameters = strtok(nullptr, "()");
    if(strcmp(dist_name, "gaussian") == 0)
    {
        double mean = atof(strtok(parameters, ","));
        double stddev = atof(strtok(nullptr, ","));
        random = [=]()
        { 
            static std::normal_distribution<double> normal_distribution(mean, stddev);
            return normal_distribution(random_engine);
        };
    }
    //...
}