2014-12-31 6 views
1
template<typename T> 
void f1(T t); 

template<typename T> 
void f2(const T t); 


template<typename T> 
void f3(T& t); 

template<typename T> 
void f4(const T& t); 


template<typename T> 
void f5(T&& t); //universal reference 

template<typename T> 
void f6(const T&& t); 

Какая разница в шаблоне функций этих шести видов?Вывод и унификация аргумента шаблона

Какова связь между выводом аргументов шаблона и объединением (общая концепция PLT)?

=== комментарий:

я знаю, чтобы получить некоторые подробности из http://en.cppreference.com/w/cpp/language/template_argument_deduction. Но этот сайт все еще запутан. Возможно, более подробное описание полезно обсудить с процессом вывода аргумента шаблона.

+2

Время, проведенное на просмотр [Презентация Скотта] (http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Scott-Meyers-Universal-References-in-Cpp11) будет хорошо израсходованы. Осмелюсь сказать, что большинство ваших вопросов, вероятно, будут рассмотрены. – WhozCraig

+0

'f1' и' f2' - это одно и то же объявление (это ограничение 'const' только в определении тела). – Jarod42

+0

Что вы подразумеваете под «Унификация (общая концепция PLT)»? –

ответ

0

Для вашего вопроса, связанного с PLT, IMHO, унификация выводит тип, когда функция определена. Тип аргумента выводится из того, как используется сама функция .

Функция шаблона-аргумента создается при его использовании . Тип аргумента передается из функции caller. Затем компилятор проверяет, соответствует ли тип аргумента тому, как аргумент используется в теле функции. Это звучит как «динамическая типизация», которая может позволить более правильный код, но потенциально отклонить менее плохой код.

Работает следующий код C++ 14. Тип автоматического аргумента внутренне реализуется с помощью шаблона.

([] (auto f, auto b) { 
    return b ? f(string("str")) : MyIntToString(f(MyInt(422))); 
})([] (auto x) { return x; }, true) 

С простым объединением следующий код типа Haskell не пройдет проверку типа.

(\f b -> if b 
     then f 1 
     else StringToNumber(f "123")) (\x -> x) True 

'е', как ожидается, будет как 'Int-> t1' и 'string-> t2', который не унифицировать.

Хиндли-Милнер тоже не поможет, так как он обобщается на «пусть», но здесь есть только аргумент лямбда.

+0

может быть «Int | String -> t»? – zpeng

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