El parámetro de la plantilla no puede ser deducido

No entiendo por qué no se puede deducir T en este escenario:

template class MyType { T * data; }; class MyOtherType { }; template struct MyType_OutArg { typedef MyType & type; }; template void DoSomething(typename MyType_OutArg::type obj) { } void func(MyType_OutArg::type obj) { DoSomething(obj); } 

Desde GCC 4.7.1 con -std = c ++ 14

 : In function 'void func(MyType_OutArg::type)': 26 : :26:20: error: no matching function for call to 'DoSomething(MyType&)' DoSomething(obj); ^ 26 : :26:20: note: candidate is: 19 : :19:1: note: template void DoSomething(typename MyType_OutArg::type) DoSomething(typename MyType_OutArg::type obj) ^ 19 : :19:1: note: template argument deduction/substitution failed: 26 : :26:20: note: couldn't deduce template parameter 'T' DoSomething(obj); ^ Compiler returned: 1 

Por supuesto los siguientes trabajos:

 DoSomething(obj); 

pero no estoy seguro de por qué es necesario. ¿No debería el comstackdor tener suficiente información?

Esto se debe a que su caso es un contexto no deducido .

Citado de http://en.cppreference.com/w/cpp/language/template_argument_deduction :

Contextos no deducidos

En los siguientes casos, los tipos, plantillas y valores no tipográficos que se utilizan para componer P no participan en la deducción de argumentos de la plantilla, sino que utilizan los argumentos de la plantilla que se dedujeron en otro lugar o se especificaron explícitamente. Si un parámetro de plantilla se usa solo en contextos no deducidos y no se especifica explícitamente, la deducción del argumento de la plantilla falla.

1) El especificador de nombre nested (todo a la izquierda del operador de resolución de scope: 🙂 ​​de un tipo que se especificó utilizando un id-calificado

En su caso, typename MyType_OutArg::type no participará en la deducción de tipo, y T no se conoce de ninguna otra parte, por lo que esta función de plantilla se ignora.