Это:
value = incr<std::remove_reference<decltype(value)>>(value); // A
не работает из-за того, что songyuanyao объяснил.
<ч />
Это:
value = incr<decltype(value)>(value); // B
не работает, потому что decltype(value)
является ссылочным типом, и вы пытаетесь создать его экземпляр:
float& incr(float& v) { return v + 1; }
int& incr(int& v) { return v + 1; }
Вы не можете связать эти выражения с неконстантными ссылками lvalue, следовательно, ошибка компиляции.
<ч />
Самое простое решение - просто позволить выводу шаблона сделать свое дело:
value = incr(value); // C
Это вызовет incr<int>
и incr<float>
по желанию.