boostorg / boostorg/graph

`depth_first_visit_impl`: `finish_edge` not invoked when it should on MSVC

未关闭
#345 2 条评论 0 个 reaction 已指派 1 人 已被 @jeremy-murphy 认领 在 GitHub 查看
algorithm priority: medium
主要语言
C++
星标
392
派生
239
平均合并
1 天 11 分钟
30 天内合并 PR
20

描述

Lines 94-104 in depth_first_search.hpp:

```c++
template < typename E, typename G, typename Vis >
void call_finish_edge(Vis& vis, E e, const G& g)
{ // Only call if method exists
#if ((defined(__GNUC__) && (__GNUC__ > 4) \
|| ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))) \
|| defined(__clang__) \
|| (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1200)))
do_call_finish_edge< has_member_function_finish_edge< Vis, void,
boost::mpl::vector< E, const G& > >::value >::call_finish_edge(vis,
e, g);
#else
do_call_finish_edge< has_member_function_finish_edge< Vis,
void >::value >::call_finish_edge(vis, e, g);
#endif
}
```

On MSVC, the section after the `#else` will not call `Vis::finish_edge` even when it is available and has the correct signature because `has_member_function_finish_edge::value` is `false`. I think this is because instead of checking that `Vis::finish_edge` exists and has return type `void` as was seemingly intended, it in facts checks that it has the exact signature `void()`. So on MSVC, even when providing a visitor type with a correct `void finish_edge(E, const G&)`, it is never called.

I don't know how to fix this because I don't know why it was determined that some compilers should be treated differently here.

I circumvented the bug in my code by adding a dummy `void finish_edge() {}` member function in my visitor type next to the actual `void finish_edge(E, const G&)` function just so the member function detection would yield `true`.

Alternatively this could be a bug in boost/tti/has_member_function.hpp but I guess that's less likely.

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。