Мой вопрос прост, но я думаю, трудно ответить.
В C ++ 14 есть ли способ проверить, имеет ли вызываемый объект (функция, член функции, лямбда-функция, 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
,
Как указано, 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
это просто неверно.
Других решений пока нет …