输入traits来检测callable是否有副作用?

时间:2016-01-25 18:15:08

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

我的问题很简单,但我猜,很难回答。

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

如果是这样,一个类型的特征如何:

template <class T>
struct has_side_effects;

会是什么样的?

我可以使用会返回假阳性的特性(说一个函数有副作用但没有),但是对于一个会返回假阴性的特性也不行(说一个函数没有副作用一样)。

例如,我想要这个特性:

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

返回false

1 个答案:

答案 0 :(得分:6)

如上所述,template<class T> 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{})有副作用。通过false后返回comparator是完全错误的。