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

时间:2018-03-09 14:57:59

标签: c++ auto

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

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);
}

3 个答案:

答案 0 :(得分:5)

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

您可以通过使用正确的签名random std::function http://leafletjs.com/reference-1.3.0.html#control-layers-addoverlay对象来解决您的问题:

std::function<double()> random;

答案 1 :(得分:3)

使用random 声明的变量类型必须编译时知道。如果您真的希望能够使用单个变量名存储不同类型的值,请查看std::variant。但是,它看起来甚至不需要使用多种类型。如果我正确理解您的代码,Private Sub btngenerar_Click() Dim wscasos As Worksheet Dim wstareas As Worksheet Dim r1 As Range Dim r2 As Range Dim cel1 As Range Dim cel2 As Range Dim vrep As Integer Dim i As Integer Dim j As Integer Dim flag As Integer Dim resultado() As Variant Dim x As Long Set wscasos = ThisWorkbook.Worksheets("Filtrados") Set wstareas = ThisWorkbook.Worksheets("Tareas") With wscasos Set r1 = .Range("B2", .Cells(.Rows.Count, .Columns("B:B").Column).End(xlUp)) End With With wstareas Set r2 = .Range("C2", .Cells(.Rows.Count, .Columns("C:C").Column).End(xlUp)) End With On Error Resume Next For Each cel1 In r1 With Application Set cel2 = .Index(r2, .Match(cel1.Value, r2, 0)) If Err = 0 Then vrep = .WorksheetFunction.CountIf(r2, cel1.Value) For i = 1 To vrep If cel2.Offset(i - 1, 4) = "Cerrado" Then flag = flag + 1 Else Exit For End If Next i If flag = vrep Then ReDim Preserve resultado(x, 1) resultado(x, 0) = cel1.Value resultado(x, 1) = cel1.Offset(, 8).Value x = x + 1 End If End If Err.Clear flag = 0 End With Next cel1 i = 0 j = 0 Sheets("Reporte").Range("A1").Select For i = LBound(resultado, 1) To UBound(resultado, 1) For j = LBound(resultado, 2) To UBound(resultado, 2) ActiveCell.Offset(i - 1, j - 1).Value = resultado(i, j) Next j Next i End Sub 应声明为具有正确签名的std::function对象。

答案 2 :(得分:1)

为了使用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);
        };
    }
    //...
}