0

我有一个 consteval crc32 函数,它在编译时工作得很好。我希望这个函数用于另一个常量内联函数。

下面是一个代码示例,以便更好地理解:

unsigned int consteval strsum(const std::string str) {
    auto n = 0;

    for (int i = 0; i < str.size(); i++) n += str.at(i);

    return n;
}

void _printHash(const unsigned int hash) {
    printf("%d", hash);
}

__forceinline void printHash(const std::string str) {
    _printHash(strsum(str));
}

int main(int argc, char* argv[]) {
    printHash("abc");
}

我希望这段代码编译为:

int main(int argc, char* argv[]) {
    _printHash(/* hash constant */);
}

相反,我收到 C7595 错误:对 consteval 函数的调用不是常量表达式。

有没有办法在 MSVC 上实现想要的行为?

4

1 回答 1

1

首先,你不能有一个带有 std::string 参数的 consteval 函数,因为它不是文字类型。幸运std::string_view的是在这个应用程序中无限好,你可以拥有

consteval unsigned int strsum(const std::string_view str) {
    auto n = 0;
    for (auto s : str) n += s;
    return n;
}

可悲的是,非consteval函数的参数永远不是常量表达式,consteval函数不能调用常规函数。所以即使你可以拥有 strsum,你也不能按照你想要的方式来称呼它。

您可以调用_printHash(strsum("abc"))而不是printHash("abc"),但是如果您不能接受这种语法,那么恐怕您没有很多选择,除了接受生成的代码将循环遍历一个常量字符串。

不是 MSVC 的编译器会在不需要任何或(或就此而言)的情况下做正确的事情,因此整个事情被编译成完全符合要求的东西。但是 MSVC 只是不太擅长这种优化。constexprconstevalinlineprintf("%d", 294)

于 2021-10-24T20:53:49.743 回答