简体   繁体   中英

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.

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>;

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM