【发布时间】:2014-01-26 02:36:58
【问题描述】:
考虑以下形式的编译时函数:
template <unsigned int Value>
constexpr unsigned int function()
{
// Just for the example, but it could be very complicated here
return Value*Value;
}
知道value 将始终在[From, To[ 区间内,如何编写将使用模板元编程调用正确编译时版本的运行时等效项:
template <unsigned int From, unsigned int To, /* Something here */>
constexpr unsigned int function(const unsigned int value)
{
// Something here
}
应该尽可能快地分支到正确的版本。
例如function<0, 32>(6)(运行时版本)应该调用function<6>()(编译时版本)。
编辑:说明:
我为什么要这样做?此功能(实际用例)需要尽可能快(超级计算问题)。通过在编译时提供参数,我可以生成非常高效的代码。如果我只是将值从模板参数移动到函数参数,代码会慢 10 到 100 倍。但实际上,此参数的可能值范围并不大(例如在0 和32 之间):因此在运行时在正确的编译时版本上进行分支会更有效率。
【问题讨论】:
-
我不明白你的问题。可以举个例子吗?
-
提供的示例是否阐明了问题?
-
如果
x在编译时未知,您将不知道function<0, 255>(x)在编译时的值。你的目标是什么? -
@PaulDraper:我认为他(有效地)在询问如何生成跳转表,所以
function<0, 255>(x)将相当于switch (x) { case 0: return function<0>(); case 1: return function<1>(); /* etc*/ default: throw "nope"; }。我过去曾问过类似的问题。您可以使用递归来做到这一点,然后依靠编译器来展开它。 (重点是您的程序可以在编译时生成function<N>的结果,您可以查看这些结果。) -
@PaulDraper 我已经添加了解释。
标签: c++ templates c++11 runtime metaprogramming