У меня есть следующая проблема: я просто не вижу правильного решения (и, возможно, нет): у меня есть шаблонный метод, в котором тип возврата зависит от ввода тип, и благодаря C++ 11 decltype
тип возврата может быть получен легко, , но Я также хотел бы разрешить пользователю задавать тип возврата явно при желании.C++ function template: Производный и явный тип возвращаемого значения
Более формально у меня есть шаблонная функция f
, что я хотел бы быть вызван как f(x)
, при этом ни входной, ни возвращаемый тип явно не определены. И я также хотел бы назвать его f<ret_t>x()
с явно выраженным типом возвращаемого значения, но тип ввода все равно будет получен автоматически.
Теперь, удовлетворяя первое ограничение с C++ 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);
Однако, этот способ мне всегда нужно явным образом d efine InT
при звонке f
. Таким образом, декларация 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
был выделен напрямую и только один раз внутри тела метода.
Последняя строка разбивается двумя способами: вы не можете УСО-использовать 'declval' и вы не можете вывести из аргумента по умолчанию. –
@Niall: Да, 'result_of', вероятно, сработает. Но проблема в том, что порядок аргументов в этом случае. –
@ T.C.: Теперь, когда вы упомянули об этом, да, вы не можете вывести из аргумента по умолчанию. Я расскажу об этом. –