gpt4 book ai didi

c++ - 在编译时构建开关

转载 作者:行者123 更新时间:2023-11-30 04:58:52 26 4
gpt4 key购买 nike

这个简单的问题是:您能否在编译时构建像 switch 一样的东西?答案是肯定的。但是我可以将这样的东西优化(或可能优化)为 switch 吗?

解释这个问题:举个例子:

假设我有一个接受整数的函数,我希望它为每个整数输入做一些不同的事情(一种行为)。这很简单,也是 switch 的经典使用案例。但是假设我有一个实现行为的类型的模板参数包,我想为这组行为编写等效于 switch 的内容,以它们在包中的索引为键。当然,这很容易实现,下面是一个示例。

我的实现的问题是开关,即使在低优化级别,也会编译成一个带有小跳转表的计算跳转。模板化的解决方案变成一组简单的 if/then/else if/... 子句,并以这种方式编译,给定足够高的优化设置。

例子可以在这里看到:

https://godbolt.org/g/fxQF1U

在该示例中,您可以在第 690 行的程序集中看到基于 switch 的实现。可以在第 804 行找到模板化版本。我还在这里包含示例的源代码以防万一链接永远消失。

我知道编译器可以根据“as if”子句尽可能多地进行优化,但是有没有一种方法可以让编译器更有可能生成更优化的代码?

#include <tuple>
#include <type_traits>
#include <any>
#include <string>
#include <vector>
#include <typeinfo>
#include <iostream>
#include <random>

template <typename... T>
struct Types {};

template <int I>
std::any get_type_name2p(int n) {
return unsigned();
}

template <int I, typename T, typename... Rest>
std::any get_type_name2p(int n) {
if (n == I) {
return T();
}
return get_type_name2p<I + 1, Rest...>(n);
}

std::any get_type_name2(int n)
{
return get_type_name2p<
0, int, float, std::string, std::vector<int>,
std::vector<float>, std::vector<double>, double, char>(n);
}

std::any get_type_name(int n)
{
switch (n) {
case 0:
return int();
case 1:
return float();
case 2:
return std::string();
case 3:
return std::vector<int>();
case 4:
return std::vector<float>();
case 5:
return std::vector<double>();
case 6:
return double();
case 7:
return char();
default:
return unsigned();
}
}

int main()
{
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<int> dist(1, 10);

auto n = dist(mt);
auto x = get_type_name(n);
std::cout << x.type().name() << std::endl;

auto y = get_type_name2(n);
std::cout << y.type().name() << std::endl;

return 0;
}

最佳答案

这是一个可能的解决方案:

std::any get_type_name(int n)
{

if ((n<0) || (n>7)) { n = 8; }
std::any types[9]=
{
int(),
float(),
std::string(),
std::vector<int>(),
std::vector<float>(),
std::vector<double>(),
double(),
char(),
unsigned()
};

return types[n];
}

关于c++ - 在编译时构建开关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51510837/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com