【问题标题】:creating a generic wrapper that returns either std::mem_fn or boost::mem_fn创建一个返回 std::mem_fn 或 boost::mem_fn 的通用包装器
【发布时间】:2015-08-27 17:04:13
【问题描述】:

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

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

现在的请求是创建一个模板函数,该函数位于 zanshin 自己的命名空间之一 (Utils::mem_fn(f)) 中,并返回 std::mem_fn(f)boost::mem_fn(f)。这部分要么高于我目前的工资等级......要么根本不可行,因为我什至几乎不了解 mem_fn 函数的目的。

所以问题是:有没有一种简单、紧凑的方式来包装std::mem_fn,理想情况下只有一个模板函数?

主要障碍似乎是返回类型,但由于 zanshin 代码中的所有使用似乎都返回归结为函数指针的内容,因此我尝试使用 void* 返回类型。我预计这会失败,确实如此。

【问题讨论】:

  • 澄清一下:“boost 依赖”是“必须安装 boost 才能构建项目”的简写,并不是为了暗示运行时依赖。我认为“他”更喜欢仅在 OS X 上添加对 boost 的构建依赖的原因是我们很可能在这里处理编译器错误。所以问题应该自己解决;不在任何地方使用 boost::mem_fn 意味着代码也将继续使用 std::mem_fn。

标签: c++ c++11 boost wrapper return-type


【解决方案1】:

“项目主要作者不倾向于增加对所有平台的boost依赖”

所以相反,他给项目带来了不一致的依赖关系?听起来很歪。

此外,它根本不是平台特定意义上的依赖项,因为您可以简单地将相关标头包含在代码库中(另请参阅 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);
   }

如果您最终在一个平台上使用 boost 实现它,只需 #ifdef 实现即可。

【讨论】:

  • 这很有趣:链接错误实际上以“decltype”开头,后面跟着一大堆杂物,在某处清楚地表明 std::mem_fn 是实际缺失的函数。我会试试你的建议;似乎它可以让我完全摆脱 boost::mem_fn ,或者我应该能够使用包装 std::mem_fn 或 boost::mem_fn 的条件形式。
  • 我同意你可以基于 std::bind 而不是 boost::mem_fn 做你自己的事情。如果没有任何随附的代码,您的链接器错误将毫无意义。我不知道您要指出的链接器错误是什么。
  • 链接错误只是为了说明;我怀疑它对任何人都有用,除了弄清楚究竟是哪种编译器错误导致它。寻找一个不涉及 boost::mem_fn 的解决方案是我将留待下一次的练习。或者生活:)
  • 好的!感谢您的澄清
猜你喜欢
  • 1970-01-01
  • 2012-07-25
  • 2020-04-24
  • 2015-07-18
  • 1970-01-01
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多