type deduction은 auto키워드를 통해 만들어지는데,
코드를 보면
#include <iostream>
int main() {
auto a = 1;
std::cout << typeid(a).name() << std::endl;
auto b = 1.1;
std::cout << typeid(b).name() << std::endl;
auto c = 1.2f;
std::cout << typeid(c).name() << std::endl;
auto d = "abc";
std::cout << typeid(d).name() << std::endl;
}
를 c++fillt -t를 이용하여 demangling된 타입을 보면

컴파일러가 알아서 타입을 지정해준 것을 알 수 있다.

이렇게 a의 타입에 맞게 
결과를 리턴해주지만

이렇게 bracket으로 타입을 설정해주면 그것에 맞춰서 결과를 리턴한다.
일반적인 함수에서 인수로 R value reference를 받는 함수에 L value를 넘겨주면

빌드가 안된다.
템플릿의 타입에서는 조금 다른데

위처럼 R value reference를 받도록 함수를 설정했는데 printVar(a)에서 L value를 받아도
실행이 된다.
이는 템플릿에서 &&는 forward reference로 R value, L value 모두 될 수 있기 때문이다.

위와 같은 함수가 있다고하면

std::string a = "nocope";가 실행되면서
위와같이 stack에 a가 생성되고 heap에 "nocope"를 가리킬 것이다.

이후 printVar(a);이 호출되면서
T와 인수가 String&으로 생성되고 string변수인 localVar가 stack frame으로 생성된다.
a와 string& a가 모두 "nocope"를 가리키지만
localVar{std::move(a)};에 의해 소유권이 바뀌면서

localVar만이 가리키게 된다.
따라서 printVar(a)함수가 끝나면서 "nocope"도 같이 소멸되고

a만 남게된다.
이후 printVar(std::move(a));가 실행되도 a가 가리키는 것이 없으니 아무것도 출력되지 않는다.


forward명령어를 통해 reference의 특성을 그대로 forward시켜주면
printVar(a);에서 a는 L value reference로 넘어왔기 때문에 그대로 L value reference놔둬서
localVar에 "nocope"가 복사된다.

이후 printVar함수가 끝나면 복사된 값도 해제된다

이후 printVar(std::move(a));가 실행되면서 R value reference로 그대로 넘겨줘
복사되지않고 move된다

이후 printVar함수가 끝나고 나머지 "nocope"도 해제된다

이후 a를 프린트해보면 가리키는 것이 없으니 아무 값도 나오지않는다.