У меня есть следующая проблема: я просто не вижу правильного решения (и, возможно, ее нет): у меня есть шаблонный метод, в котором тип возврата зависит от типа ввода и благодаря С++ 11 decltype
тип возврата может быть легко получен, но я также хотел бы позволить пользователю явно определять тип возвращаемого значения, если это необходимо.
Более формально у меня есть шаблонная функция f
, которую я хотел бы назвать вызываемым как f(x)
, при этом ни тип ввода, ни возвращаемый тип явно не определены. И я также хотел бы иметь возможность называть его как f<ret_t>x()
с явно выраженным типом возвращаемого значения, но тип ввода все равно получается автоматически.
Теперь, удовлетворяя первому ограничению с С++ 11, легко (предположим, что есть еще один шаблонный метод:
template<typename InT>
auto f(const InT& in) -> decltype(/* code deriving the return type using in */);
Но это не позволит переопределить возвращаемый тип, для этого мне пришлось бы добавить его в качестве второго параметра шаблона и переместить вывод decltype
в определение шаблона и, вероятно, нужно будет использовать std::declval<InT>
или std::result_of
template<
typename InT,
typename RetT = /* code deriving return type using InT and declval/result_of */>
RetT f(const InT& in);
Тем не менее, при вызове f
мне всегда нужно также явно определять InT
. Таким образом, объявление f
для того, чтобы оставить InT
открытым, но указать RetT
должно быть:
template<
typename RetT = /* code deriving return type using InT and declval/result_of */,
typename InT>
RetT f(const InT& in);
Но так как в точке, где мне нужно указать значение по умолчанию для RetT
, InT
пока недоступно и, следовательно, не может быть использовано.
Лучшее обходное решение, которое я мог бы придумать до сих пор, которое не очень удовлетворительно и, похоже, не работает, поскольку вычет RetT
не выполняется (видимо, из-за того, что вы не можете выводить типы из аргументов по умолчанию), есть:
template<typename RetT, typename InT>
RetT f(
const InT& in,
const RetT& = std::declval</* code deriving return type using InT or in and declval/result_of */>());
Есть ли лучшие способы иметь значение по умолчанию для RetT
, которое зависит от InT
, но при этом может явно указывать RetT
, если это необходимо? Важно отметить, что тип возвращаемого значения должен быть доступен в реализации функции для того, чтобы объект RetT
был назначен напрямую и только один раз внутри тела метода.