С С++ 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
, я считаю, поступил правильно).