我有一个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
。
我在这里缺少什么?
答案 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 ++编译器在运行时命名新类型。所以,我们有一个强制在编译时运行的东西;在c++14中我们有模板常量:
template<uint32_t v>
std::integral_constant< uint32_t, v > kint32{};
有了这个,我们可以做到:
uniformByNameCRC32(kint32<ctcrc32("uPointLight.position")>);
应该在编译时执行ctcrc32
。不这样做需要编译器批次的工作。
在c++17中你甚至可以这样做:
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);