有没有办法以某种方式重载函数,以区分在编译时或运行时可评估的参数?
假设我有以下功能:
std::string lookup(int x) {
return table<x>::value;
}
允许我在恒定时间内(基于空间开销)基于参数x选择字符串值。但是,在某些情况下,在编译时无法提供x
,我需要运行foo版本,以更高的时间复杂度进行查找。
我当然可以使用不同名称的函数,但我希望有一个统一的界面。
我接受了一个答案,但我仍然感兴趣的是,如果可以使用完全相同的函数调用进行区分。
答案 0 :(得分:2)
一种选择是以类似的方式使用重载:
template <int x> std::string find() {
return table<x>::value;
}
std::string find(int x) {
return ...
}
答案 1 :(得分:2)
我相信你最接近的是lookup
和int
上的std::integral_constant<int>
重叠;那么,如果调用者知道compile-type的值,他们可以调用后者重载:
#include <type_traits>
#include <string>
std::string lookup(int const& x) // a
{
return "a"; // high-complexity lookup using x
}
template<int x>
std::string lookup(std::integral_constant<int, x>) // b
{
return "b"; // return table<x>::value;
}
template<typename T = void>
void lookup(int const&&) // c
{
static_assert(
!std::is_same<T, T>{},
"to pass a compile-time constant to lookup, pass"
" an instance of std::integral_constant<int>"
);
}
template<int N>
using int_ = std::integral_constant<int, N>;
int main()
{
int x = 3;
int const y = 3;
constexpr int z = 3;
lookup(x); // calls a
lookup(y); // calls a
lookup(z); // calls a
lookup(int_<3>{}); // calls b
lookup(3); // calls c, compile-time error
}
的 Online Demo 强>
注意:
int_
帮助器,因此std::integral_constant<int>
的构造对于调用者来说不那么冗长;这是可选的。constexpr int
变量传递给重载a,而不是重载c),但这会清除任何实际的int文字。答案 2 :(得分:0)
还有这个技巧:
std::string lookup(int x) {
switch(x) {
case 0: return table<0>::value;
case 1: return table<1>::value;
case 2: return table<2>::value;
case 3: return table<3>::value;
default: return generic_lookup(x);
}
当对整数在编译时已知是有利的但不是必需的时,这种事情会很好地起作用。例如,是否对优化器有所帮助。如果您以这种方式调用某个复杂函数的许多实例,那么在编译时可能会很麻烦。