【问题标题】:Type traits to detect if a callable has side effects?键入特征以检测可调用对象是否具有副作用?
【发布时间】:2016-05-02 03:58:36
【问题描述】:

我的问题问起来很简单,但我想,很难回答。

在 C++14 中,有没有办法测试可调用(函数、函数成员、lambda 函数、std::function 等)是否有副作用?

如果是这样,类型特征将如何:

template <class T>
struct has_side_effects;

会喜欢吗?

我可以接受会返回误报的特征(说函数有副作用而它没有),但不能接受会返回误报的特征(说函数没有副作用,而它确实)。

例如,我想要 trait:

auto comparator = [](const auto& x, const auto& y){return y > x;};
bool result = std::has_side_effects<decltype(comparator)>::value;

返回false

【问题讨论】:

  • 这是不可能的,除非函数是 constexpr
  • 静态分析器可能会有所帮助......但这似乎不是一项简单的任务。
  • @DieterLücking constexpr 也不可能,除非由实施者保证。 constexpr 函数允许有导致副作用的分支。
  • 这似乎可以减少到停机问题,不是吗?
  • @erip:如果不允许误报,它只会减少到停止问题。否则,正如 Yakk 所说,有一个简单的算法只是说“一切都有副作用”:-)

标签: c++ function c++14 template-meta-programming side-effects


【解决方案1】:

如上所述,template&lt;class T&gt; using has_side_effects = std::true_type; 解决了您的大部分问题。简单地说一切都有副作用,然后发货。误报,但没有误报!

通常,无法计算在图灵完备系统中编码的算法的重要属性。这样做等同于停机问题。所以这个问题一般不能解决。

在特定情况下,C++ 对算法内容的反射基本上为零。充其量它提供了对算法的接口的一些反映,但算法/函数的接口不包含有关算法纯度的信息。

您可以获得的最接近的是“可以在constexpr 上下文中调用它”。

具体情况:

auto comparator = [](const auto& x, const auto& y){return y > x;};
bool result = std::has_side_effects<decltype(comparator)>::value;

结果必须是true,如:

struct evil {
  static int count() { static int r = 0; return ++r; }
  friend bool operator<( evil lhs, evil rhs ) { count(); return false; }
};

那么comparator(evil{}, evil{}) 有副作用。在通过 comparator 时让它返回 false 是完全不正确的。

【讨论】:

  • 一般来说,在图灵完备系统中编码的算法的非平凡属性无法计算。对于感兴趣的人,这是莱斯定理。
  • @erip 公平地说 赖斯定理是关于图灵机接受的语言。您实际上可以处理计算本身的重要属性(例如,“它会接受不到一百万步吗?”)。将“有副作用”翻译成“接受语言的属性”需要一点时间:你重新编码你的抽象机器,当它产生副作用时在磁带上写“X”,然后是一种接受带有列表的字符串的语言如果输入到原始算法的字符串输出了那么多 X,则为 X。
  • 确实如此。我试图想出一些减少的方法,这很难
猜你喜欢
  • 2017-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-09
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多