С С++ 17 у нас есть fancy new is_invocable и новые новые значения, которые на самом деле не являются значениями.
Это позволяет вам создать объект без необходимости его логического построения, а затем завершить конструкцию.
У меня возникла проблема, когда использование std::is_invocable для проверки, если вы можете что-то вызывать, и правила prvalue, похоже, сталкиваются:
struct no_move {
no_move(no_move&&)=delete;
explicit no_move(int) {}
};
void f( no_move ) {}
теперь мы можем спросить, можно ли вызвать f, используя prvalue типа no_move?
f( no_move(1) )
std::is_invocable< decltype(&f), no_move > не работает, поскольку использует std::declval<no_move>(), который является значением x, как no_move&&, а не значением класса no_move.
В С++ 14 это было то же, но гарантированное elision делает некоторые функции вызываемыми с xvalue (т.е. "T&&" ), а другие с prvalues типа T.
Есть ли альтернатива, или нам нужно придумать свою собственную черту для обработки этого случая?
(В теоретическом мире, где std::declval<T> вернул T вместо T&&, is_invocable, я считаю, поступил правильно).