参数的重载函数(不)在编译时可以推断

时间:2016-01-14 14:58:09

标签: c++ c++11 overloading

有没有办法以某种方式重载函数,以区分在编译时或运行时可评估的参数?

假设我有以下功能:

 std::string lookup(int x) {
     return table<x>::value;
 }

允许我在恒定时间内(基于空间开销)基于参数x选择字符串值。但是,在某些情况下,在编译时无法提供x,我需要运行foo版本,以更高的时间复杂度进行查找。

我当然可以使用不同名称的函数,但我希望有一个统一的界面。

我接受了一个答案,但我仍然感兴趣的是,如果可以使用完全相同的函数调用进行区分。

3 个答案:

答案 0 :(得分:2)

一种选择是以类似的方式使用重载:

template <int x> std::string find() {
   return table<x>::value;
}

std::string find(int x) {
    return ...
}    

答案 1 :(得分:2)

我相信你最接近的是lookupint上的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>的构造对于调用者来说不那么冗长;这是可选的。
  • 重载c将有误报(例如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);
}

当对整数在编译时已知是有利的但不是必需的时,这种事情会很好地起作用。例如,是否对优化器有所帮助。如果您以这种方式调用某个复杂函数的许多实例,那么在编译时可能会很麻烦。