Overload function for (non) arguments output at compile time

Is there a way to overload a function in such a way as to distinguish between the argument to be analyzed at compile time or only at run time?

Suppose I have the following function:

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

which allows me to select a string value based on the x parameter in constant time (with spatial overhead). However, in some cases xit cannot be provided at compile time, and I need to run a version of foo that does a search with higher time complexity.

I could use functions with a different name, of course, but I would like to have a unified interface.


I accepted the answer, but I'm still wondering if this difference is possible with the same function call.

+4
source share
2 answers

I believe that the closest you can overload lookupto intand std::integral_constant<int>; then, if the caller knows the value in the compiler, it can cause the last overload:

#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
}

-

Notes:

  • I provided an assistant int_, so the construction is std::integral_constant<int>less verbose for the caller; it's not obligatory.
  • Overloading c will have false negatives (for example, constexpr intvariables are passed for overloading a, not overloading c), but this will save you from any actual int literals.
+2
source

One option is to use overload in a similar way:

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

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

Source: https://habr.com/ru/post/1624295/


All Articles