运行 时间的 C++20 constexpr std::copy 优化
C++20 constexpr std::copy optimizations for run-time
In practice, implementations of std::copy avoid multiple assignments and use bulk copy functions such as std::memmove if the value type is TriviallyCopyable
但是,该页面还指出,自 C++20 起,不采用执行策略的重载将是 constexpr
。标准会禁止这些 运行 时间的优化(因为 std::memmove
不是 constexpr)还是有办法优化 运行 时间的 constexpr
函数?
我们也可以吃蛋糕吃。
让我们考虑最简单的 copy
特化,即复制 char
的特化。在 C++17 中,它可能看起来像:
char* copy(char const* first, char const* last, char* d)
{
memcpy(d, first, last - first);
return d + (last - first);
}
当然,我们不能就此打上 constexpr
,因为 memcpy
不是一个 constexpr 函数,那是行不通的。但它只在不断评估期间不起作用。我们需要的是一种在运行时有条件地使用 memcpy
的方法。
我们在C++20中有这样的东西,std::is_constant_evaluated()
:
constexpr char* copy(char const* first, char const* last, char* d)
{
if (std::is_constant_evaluated()) {
while (first != last) {
*d++ = *first++;
}
return d;
} else {
memcpy(d, first, last - first);
return d + (last - first);
}
}
现在我们有了一个算法,它可以在运行时执行高效的操作,但在 constexpr 评估期间仍然有效。
注:是if (std::is_constant_evaluated())
,从不 if constexpr (std::is_constant_evaluated())
。后者相当于if constexpr (true) { ... }
。 gcc 10.1 将开始警告这种错误用法。
In practice, implementations of std::copy avoid multiple assignments and use bulk copy functions such as std::memmove if the value type is TriviallyCopyable
但是,该页面还指出,自 C++20 起,不采用执行策略的重载将是 constexpr
。标准会禁止这些 运行 时间的优化(因为 std::memmove
不是 constexpr)还是有办法优化 运行 时间的 constexpr
函数?
我们也可以吃蛋糕吃。
让我们考虑最简单的 copy
特化,即复制 char
的特化。在 C++17 中,它可能看起来像:
char* copy(char const* first, char const* last, char* d)
{
memcpy(d, first, last - first);
return d + (last - first);
}
当然,我们不能就此打上 constexpr
,因为 memcpy
不是一个 constexpr 函数,那是行不通的。但它只在不断评估期间不起作用。我们需要的是一种在运行时有条件地使用 memcpy
的方法。
我们在C++20中有这样的东西,std::is_constant_evaluated()
:
constexpr char* copy(char const* first, char const* last, char* d)
{
if (std::is_constant_evaluated()) {
while (first != last) {
*d++ = *first++;
}
return d;
} else {
memcpy(d, first, last - first);
return d + (last - first);
}
}
现在我们有了一个算法,它可以在运行时执行高效的操作,但在 constexpr 评估期间仍然有效。
注:是if (std::is_constant_evaluated())
,从不 if constexpr (std::is_constant_evaluated())
。后者相当于if constexpr (true) { ... }
。 gcc 10.1 将开始警告这种错误用法。