类型可以由编译时已知的对象创建(或模板实例化)吗?

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 将执行 ifswitch 不是解决方案 - 这将是很多代码并且很慢。

这是您函数的调用语法:

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

Demo

最终你最好坚持 for now until constexpr function parameters (P1045) 是标准化的(或类似的东西)。