Почему шаблонный параметр функции разрешен, но не шаблонный тип возврата?

У меня были следующие биты кода:

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow)
{
 int serialport = getCommandLineOption<int>(lpCmdLine, "-com", atoi);
 ...

template<typename t="">
T getCommandLineOption(const std::string& commandLine, const std::string& option, std::function<t(const char*)=""> f)
{
 auto result = getCommandLineOption(commandLine, option);
 return result.empty() ? T() : f(result.c_str());
}

const std::string getCommandLineOption(std::string commandLine, std::string option)
{
 ...
</t(const></typename></int>

а затем я удалил включение functional заголовка и изменил функцию шаблона на:

template<typename t,="" typename="" f="">
T getCommandLineOption(const std::string& commandLine, const std::string& option, F f)
{
 auto result = getCommandLineOption(commandLine, option);
 return result.empty() ? T() : f(result.c_str());
}
</typename>

теперь в WinMain где я вызываю функцию для получения параметра последовательного порта, я не могу опустить спецификацию типа int, но я могу опустить спецификацию типа указателя функции. Зачем?

PS: функции getCommandLineOption находятся в статической библиотеке, статическая библиотека используется проектом, содержащим WinMain.

1 ответ

Тип возврата не может быть выведен компилятором. Вы можете использовать:

template<typename f="">
auto
getCommandLineOption(const std::string& commandLine, const std::string& option, F f)
-> decltype(f(getCommandLineOption(commandLine, option).c_str()))
// or decltype(f(declval<const char*="">()))
{
 auto result = getCommandLineOption(commandLine, option);
 return result.empty() ? decltype(f(result.c_str())){} : f(result.c_str());
}
</const></typename>

Живой пример

licensed under cc by-sa 3.0 with attribution.