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)>);
}
Ultimately you're better sticking to bolov's answer for now until constexpr function parameters (P1045) is standardized (or something similar to it).