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

Time:03-24

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.

CodePudding user response:

This is the calling syntax for your function:

auto x = foo(std::integral_constant<int, 24>{});
// or
auto y = foo<int, 24>({});

However you don't need the integral_constant. You can simplify to this:

template <int value>
auto bar()
{
     if constexpr (value == 0)
         return int{};
     else
         return float{};
}

auto test()
{
    auto x = bar<24>();
}

But from your description even that is not what you actually want. Although is not very clear it looks like you want a type based on a value. If that is the case then you need a type alias, not a function, because functions return values and not types.

Here is the type alias version:

template <int Value>
struct my_type
{
    using type = float;
};


template <>
struct my_type<0>
{
    using type = int;
};

template <int Value>
using my_type_t = typename my_type<Value>::type;


using T = my_type_t<24>;
using U = my_type_t<0>;

CodePudding user response:

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).

  • Related