Ответ в основном взят из книги Скотта Майерса Эффективная книга C ++ .
template<typename T>
void f(ParamType param);
f(expr); // deduce T and ParamType from expr
ParamType является ссылкой или указателем, но не универсальной ссылкой
Простейшая ситуация - это когда ParamType является ссылочным типом или типом указателя, но не универсальной ссылкой. В этом случае вычитание типа работает следующим образом:
- Если тип expr является ссылкой, игнорируйте ссылочную часть.
- Затем сопоставьте тип выражения expr с ParamType, чтобы определить T.
В процессе вывода аргументов игнорируется ссылочная часть, а не const
.
В вашем случае это const auto &actions = state.actions;
, что означает для шаблона вычет аргумента auto soln = func(actions[0], false);
отбрасывается только ссылочная часть, а не cv .
Дополнительные примеры из книги.
template<typename T>
void f(T& param); // param is a reference
и у нас есть эти переменные декларации,
int x = 27; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
the deduced types for param and T in various calls are as follows:
f(x); // T is int, param's type is int&
f(cx); // T is const int,
// param's type is const int&
f(rx); // T is const int,
// param's type is const int&