C++ 在知道其类型之前使用自动定义的变量
C++ Using an auto-defined variable before knowing its type
我目前正在尝试在不知道其类型之前使用自动定义的变量。为什么?因为类型取决于程序输入。如果用户选择某个分布,程序将根据该分布输出值。这是代码:
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. However, it does also look like you don't even need to use multiple types. If I understand your code correctly, random
should be declared as an 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);
};
}
//...
}
我目前正在尝试在不知道其类型之前使用自动定义的变量。为什么?因为类型取决于程序输入。如果用户选择某个分布,程序将根据该分布输出值。这是代码:
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. However, it does also look like you don't even need to use multiple types. If I understand your code correctly, random
should be declared as an 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);
};
}
//...
}