2015-11-19 2 views
6

Есть ли способ использовать автоматическое ключевое слово в этом сценарии:Использование авто в выходном параметре

void foo(bar& output){ 
    output = bar(); 
} 

int main(){ 
    //Imaginary code 
    auto a; 
    foo(a); 
} 

Конечно, невозможно знать, какой тип a. Таким образом, решение должно заключаться в том, чтобы объединить их в одном предложении так или иначе. Это доступно?

+2

Я так не думаю .. Что произойдет, если вы добавите перегрузку в 'foo'? –

+1

Если вы не знаете тип 'a' при написании программы, у вас есть невозможная проблема. Для функции решение является шаблоном, но вам нужно знать тип переменной, которую вы объявляете, так или иначе. –

+0

Простой ответ - нет (BTW Что вы имеете в виду, объединив их в одно предложение). –

ответ

10

Похоже, вы хотите инициализировать по умолчанию объект типа, который данная функция ожидает в качестве аргумента.

Вы не можете сделать это с помощью auto, но вы могли бы написать черту, чтобы извлечь тип функция ожидает, а затем использовать, чтобы объявить переменную:

namespace detail { 
    //expects the argument number and a function type 
    template <std::size_t N, typename Func> 
    struct arg_n; 

    //does all the work 
    template <std::size_t N, typename Ret, typename... Args> 
    struct arg_n <N, Ret (Args...)> { 
     using type = std::remove_reference_t< 
         std::tuple_element_t<N, std::tuple<Args...>> 
        >; 
    }; 
} 

//helper to make usage neater 
template <std::size_t N, typename Func> 
using arg_n = typename detail::arg_n<N, Func>::type; 

Тогда вы используете его так:

//type of the first argument expected by foo 
arg_n<0,decltype(foo)> a{}; 
foo(a); 

Конечно, как только вы перегружаете функцию, все это терпит неудачу.

+0

Это потрясающе, хотя я не понял весь шаблон, но результат - именно то, что я хочу. Тем не менее, я боюсь использовать его в реальной программе, потому что кто-то (несколько лет спустя) пожелает, чтобы тот, кто пишет этот код, отправился в ад: D –

+0

@HumamHelfawi На самом деле, этот вид кода довольно нормальный в общем контексте , Возможно, вам понадобятся еще несколько комментариев, если вы считаете, что поддерживающие найдут его тупым. – TartanLlama

4
bar foo() 
{ 
    return bar{}; 
} 

int main() 
{ 
    auto a = foo(); 
} 

Все современные компиляторы сделают копирование, копии не будут вообще.

+0

Хотя это показывает использование авто, он избегает вопроса, потому что он не использует параметр out. –

+0

@ChrisBetti В этой ситуации лучше не передавать ссылку на какой-либо построенный экземпляр, а затем назначать ему новый экземпляр. Лучше возвратитесь по значению и назначьте его вновь созданной переменной 'auto'. – vladon

+0

100% согласен с вами. –

Смежные вопросы