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

Vin*_*ent 2 c++ function side-effects template-meta-programming c++14

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

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

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

template <class T>
struct has_side_effects;
Run Code Online (Sandbox Code Playgroud)

会是什么样的?

我可以使用会返回假阳性的特性(说一个函数有副作用而不是它),但是对于一个会返回假阴性的特性不好(说一个函数没有副作用).

例如,我想要的特点:

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

返回false.

Yak*_*ont 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;
Run Code Online (Sandbox Code Playgroud)

结果必须true如下:

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

然后comparator(evil{}, evil{})有副作用.在false传递时返回它comparator是完全错误的.

  • _通常,无法计算在图灵完备系统中编码的算法的非平凡属性.对于那些感兴趣的人,这是赖斯的定理. (2认同)