GCC 手工制作的 constexpr 查找 vs std::find
GCC hand made constexpr find vs std::find
我正在尝试使用 c++17 实现 constexpr 查找,以查找数组中匹配元素的索引 (from cppreference) very similar to 。下面是一个非常简单的实现,其中包含 int
数组。
namespace mine{
template<typename InputIter, typename T>
constexpr inline InputIter find(InputIter first, InputIter last, const T& val)
{
for(; first!=last; ++first)
if(*first == val) return first;
return first;
}
}
int main()
{
const std::array<int, 5> a{4, 10, 5, 889, 45};
auto b = mine::find(a.begin(), a.end(), 5);
auto c = std::distance(a.begin(), b);
return c;
}
问题是 GCC 主干无法在编译时推断 mine::find
!! (live code mine::find
)。
然而,只需将开关更改为 -std=c++2a
(因为 c++20 将 std::find
标记为 constexpr
),std::find
会给我预期的结果 (live code std::find
) .
编辑: 如何在不更改 main()
中的代码的情况下获得与 std::find
和 mine::find
相同的优化级别相同的结果? (mind::find
当然可以更改,保持类似的界面)
是什么让 GCC 针对相同的优化级别优化 std::find
更好?
编辑 2: 在此处将 b
声明为 constexpr
会产生错误 (live code with error)
int main()
{
const std::array<int, 5> a{4, 10, 5, 889, 45};
constexpr auto b = mine::find(a.begin(), a.end(), 5);
auto c = std::distance(a.begin(), b);
return c;
}
注意:Clang trunk 似乎可以正确推断 mine::find
。但这与 constexpr
恕我直言没什么关系,因为即使没有它,clang 也会推断出结果。
除非在 const 表达式中使用,否则不需要在编译时调用 constexpr 函数。然后你依赖编译器优化。
在 constexpr 中转换您的(调用)代码可确保编译时计算:
int main()
{
static constexpr std::array<int, 5> a{4, 10, 5, 889, 45};
constexpr auto b = mine::find(a.begin(), a.end(), 5);
constexpr auto c = std::distance(a.begin(), b);
return c; // return 2 directly
}
我正在尝试使用 c++17 实现 constexpr 查找,以查找数组中匹配元素的索引 (from cppreference) very similar to int
数组。
namespace mine{
template<typename InputIter, typename T>
constexpr inline InputIter find(InputIter first, InputIter last, const T& val)
{
for(; first!=last; ++first)
if(*first == val) return first;
return first;
}
}
int main()
{
const std::array<int, 5> a{4, 10, 5, 889, 45};
auto b = mine::find(a.begin(), a.end(), 5);
auto c = std::distance(a.begin(), b);
return c;
}
问题是 GCC 主干无法在编译时推断 mine::find
!! (live code mine::find
)。
然而,只需将开关更改为 -std=c++2a
(因为 c++20 将 std::find
标记为 constexpr
),std::find
会给我预期的结果 (live code std::find
) .
编辑: 如何在不更改 main()
中的代码的情况下获得与 std::find
和 mine::find
相同的优化级别相同的结果? (mind::find
当然可以更改,保持类似的界面)
是什么让 GCC 针对相同的优化级别优化 std::find
更好?
编辑 2: 在此处将 b
声明为 constexpr
会产生错误 (live code with error)
int main()
{
const std::array<int, 5> a{4, 10, 5, 889, 45};
constexpr auto b = mine::find(a.begin(), a.end(), 5);
auto c = std::distance(a.begin(), b);
return c;
}
注意:Clang trunk 似乎可以正确推断 mine::find
。但这与 constexpr
恕我直言没什么关系,因为即使没有它,clang 也会推断出结果。
除非在 const 表达式中使用,否则不需要在编译时调用 constexpr 函数。然后你依赖编译器优化。
在 constexpr 中转换您的(调用)代码可确保编译时计算:
int main()
{
static constexpr std::array<int, 5> a{4, 10, 5, 889, 45};
constexpr auto b = mine::find(a.begin(), a.end(), 5);
constexpr auto c = std::distance(a.begin(), b);
return c; // return 2 directly
}