创建一个 returns std::mem_fn 或 boost::mem_fn 的通用包装器

creating a generic wrapper that returns either std::mem_fn or boost::mem_fn

KDE/PIM Zanshin 项目在其代码中的多个位置使用了 std::mem_fn,事实证明至少有 1 个版本的 Apple 的 clang(附带最新的 Xcode 可用于 OS X 10.9) 生成的目标代码无法 link 涉及的许多文件。

原来可以通过使用 boost::mem_fn 而不是 std::mem_fn 来规避这个问题。该项目的主要作者不倾向于增加对所有平台的boost依赖,所以我提出了一个补丁,其中使用条件宏在需要时扩展为boost::mem_fn

现在的要求是创建一个模板函数,该函数位于 zanshin 自己的命名空间之一 (Utils::mem_fn(f)) 中,并且 return 是 std::mem_fn(f)boost::mem_fn(f)。那就是高于我当前薪资等级的部分……或者这根本不可行,我什至几乎不了解 mem_fn 函数的目的。

所以问题是:是否有一种 简单 的紧凑方式来包装 std::mem_fn,最好使用单个模板函数?

主要障碍似乎是 return 类型,但由于 zanshin 代码中的所有使用似乎 return 归结为函数指针,我尝试使用 void* return 类型。我原以为会失败,结果确实如此。

"The project's main author is not inclined to increase the boost dependency on all platforms"

所以他反而给项目增加了不一致的依赖项?听起来很乱。

此外,它根本不是 platform-specific 意义上的依赖关系,因为您可以简单地将相关的 headers 包含在代码库中(另请参见 BCP)并且在第一名。

也就是说,更简单的选择是使用一个包装器来包装 std::mem_fn 并同时练习(地址)引用的成员。这样一来,联动问题就应该真正消失了。

最简单的是 (c++14):

template <typename PTMorPTMF>
    auto my_mem_fn(PTMorPTMF const& ptm) { 
        return std::mem_fn(ptm);
    }

如果你被 c++11 困住了:

template <typename PTMorPTMF>
    auto my_mem_fn(PTMorPTMF const& ptm) -> decltype(std::mem_fn(ptm)) { 
        return std::mem_fn(ptm);
   }

简单地 #ifdef 如果您最终在一个平台上使用 boost 实现它。