使用constexpr函数的返回值作为另一个函数的参数

时间:2017-10-30 17:49:26

标签: c++ templates c++14 constexpr

我有一个constexpr函数,用于从字符串文字计算CRC32哈希值。

template <size_t len>
constexpr uint32_t ctcrc32(const char (&str)[len]) {
    return detail::crc32<len - 2>(str) ^ 0xFFFFFFFF;
}

(它指的是其他constexpr函数)

我想要做的是调用一些接受uint32_t值的其他函数,并使用它来访问某些unordered_map中的数据。这样的电话看起来像这样:

uniformByNameCRC32(ctcrc32("uPointLight.position"));

我希望"uPointLight.position"的哈希值在构建时计算一次,然后将结果常量传递给uniformByNameCRC32(),但情况并非如此,并且ctcrc32()被调用在运行时基本上会杀死CPU,因为我有很多uniformByNameCRC32()次调用。

然而,这可以正常工作:

std::array<uint64_t, ctcrc32("string_literal")> array;

此类代码会编译并指出ctcrc32()的返回值确实为constexpr

我在这里缺少什么?

3 个答案:

答案 0 :(得分:3)

OP询问(在评论中)

  

如何将它包装在某个宏中,因为我不想每次都写两行代码

我想你可以使用一个接收var factory = new VehicleServiceFactory(); Vehicle vehicle = GetCar(); var vehicleService = factory.GetVehicleService<Car>(vehicle); //Explicit type vehicleService.ServiceVehicle(vehicle); 值作为模板值的函数,然后简单地返回它。

我的意思是

ctcrc32

您可以按如下方式使用

template <uint32_t N>
constexpr uint32_t getCV () // get constexpr value
 { return N; }

uniformByNameCRC32(getCV<ctcrc32("uPointLight.position")>()); 值作为模板参数传递给ctcrc32(),强制编译器计算编译时间。

答案 1 :(得分:3)

无法保证在编译时与C ++中的运行时间相比完成任何操作。理论上,C ++允许您的代码在运行时作为字符串文字传递给C ++解释器。 (对于某些格式错误的程序有一些强制性诊断,但未指定所述诊断的形式,即使没有不良形式,也允许您发出诊断信息,因此只需打印出一行“此代码”将在稍后编制“满足标准”。

constexpr只是让你在传统上在编译时完成的代码中做一些事情,比如堆栈上的大小数组或者使用类型名称中的常量。

没有主要的C ++编译器在运行时命名新类型。所以,我们有一个强制在编译时运行的东西;在中我们有模板常量:

template<uint32_t v>
std::integral_constant< uint32_t, v > kint32{};

有了这个,我们可以做到:

uniformByNameCRC32(kint32<ctcrc32("uPointLight.position")>);

应该在编译时执行ctcrc32。不这样做需要编译器批次的工作。

中你甚至可以这样做:

template<auto x>
std::integral_constant< std::decay_t<decltype(x)>, x > k{};

它适用于任何类型。

std::integral_constant依次隐式转换回相同类型的值。

答案 2 :(得分:2)

使用中间constrexpr变量:

constexpr auto value = ctcrc32("uPointLight.position")
uniformByNameCRC32(value);