类型可以由编译时已知的对象创建(或模板实例化)吗?
Can type be created(or template instantiated) by object known at compile time?
假设我有一个模板函数:
template <typename T, T value>
auto foo(std::integral_constant<T, value>)
{
if constexpr (value == 0)
{
return int{};
}
else
{
return float{};
}
}
我想用一个数字常量来调用它:
foo(4);
能实现吗?如果不是,为什么?
我知道我可以自己创建 std::integral_constant
,但我对从对象创建类型的想法很感兴趣。在上面的示例中,我将 4
作为对象,将 std::integral_constant
作为类型。
声明一些 define
将执行 if
或 switch
不是解决方案 - 这将是很多代码并且很慢。
这是您函数的调用语法:
auto x = foo(std::integral_constant<int, 24>{});
// or
auto y = foo<int, 24>({});
但是您不需要 integral_constant
。您可以简化为:
template <int value>
auto bar()
{
if constexpr (value == 0)
return int{};
else
return float{};
}
auto test()
{
auto x = bar<24>();
}
但从你的描述来看,这并不是你真正想要的。虽然不是很清楚,但看起来你想要一个基于值的类型。如果是这种情况,那么您需要一个类型别名,而不是一个函数,因为函数 return 值而不是类型。
这里是类型别名版本:
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>;
我绝对不推荐这样做,但您可以使用宏来实现您所追求的语法:
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)>);
}
最终你最好坚持 for now until constexpr function parameters (P1045) 是标准化的(或类似的东西)。
假设我有一个模板函数:
template <typename T, T value>
auto foo(std::integral_constant<T, value>)
{
if constexpr (value == 0)
{
return int{};
}
else
{
return float{};
}
}
我想用一个数字常量来调用它:
foo(4);
能实现吗?如果不是,为什么?
我知道我可以自己创建 std::integral_constant
,但我对从对象创建类型的想法很感兴趣。在上面的示例中,我将 4
作为对象,将 std::integral_constant
作为类型。
声明一些 define
将执行 if
或 switch
不是解决方案 - 这将是很多代码并且很慢。
这是您函数的调用语法:
auto x = foo(std::integral_constant<int, 24>{});
// or
auto y = foo<int, 24>({});
但是您不需要 integral_constant
。您可以简化为:
template <int value>
auto bar()
{
if constexpr (value == 0)
return int{};
else
return float{};
}
auto test()
{
auto x = bar<24>();
}
但从你的描述来看,这并不是你真正想要的。虽然不是很清楚,但看起来你想要一个基于值的类型。如果是这种情况,那么您需要一个类型别名,而不是一个函数,因为函数 return 值而不是类型。
这里是类型别名版本:
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>;
我绝对不推荐这样做,但您可以使用宏来实现您所追求的语法:
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)>);
}
最终你最好坚持