Search code examples
c++metaprogrammingtemplate-meta-programmingmetaclass

Can type be created(or template instantiated) by object known at compile time?


Suppose I have a template function:

template <typename T, T value>
auto foo(std::integral_constant<T, value>)
{
     if constexpr (value == 0)
     {
         return int{};
     }
     else
     {
         return float{};
     }
}

And I want to call it using a number constant:

foo(4);

Can it be implemented? If no, why?

I see that I can create std::integral_constant on my own, but I'm interested in the idea of creating a type from an object. In the example above, I have 4 as the object and std::integral_constant as the type.

Declaring some define which will do if or switch is not a solution - it will be a lot of code and slow.


Solution

  • I absolutely do not recommend this, but you could use a macro to achieve the syntax you're after:

    template <auto value>
    auto foo_impl()
    {
         if constexpr (value == 0)
         {
             return int{};
         }
         else
         {
             return float{};
         }
    }
    
    #define foo(constant) foo_impl<constant>()
    
    
    int main(){
        auto should_be_int = foo(0);
        static_assert(std::is_same_v<int, decltype(should_be_int)>);
    
        auto should_be_float = foo(1);
        static_assert(std::is_same_v<float, decltype(should_be_float)>);
    }
    

    Demo

    Ultimately you're better sticking to bolov's answer for now until constexpr function parameters (P1045) is standardized (or something similar to it).