Шаблон C ++ Funtion с гибким типом возврата - PullRequest
1 голос
/ 07 октября 2019

Я пытался реализовать проверку работоспособности входов с помощью шаблонного программирования. Моя функция проверки работоспособности выглядит следующим образом:

template<typename T> T getInput(std::string& _input) {
std::cin >> _input;
if(std::is_same<T, int>::value) {
    try{
        auto result=std::stoi(_input);
        return(result);
    }
    catch(std::invalid_argument& except) {
        std::cout << except.what() << "\n";
    }
}
else if(std::is_same<T, unsigned int>::value) {
    try{
        auto result=std::stoul(_input);
        return(result);
    }
    catch(std::invalid_argument& except) {
        std::cout << except.what() << "\n";
    }
}
else if(std::is_same<T, float>::value) {
    try{
        auto result=std::stof(_input);
        return(result);
    }
    catch(std::invalid_argument& except) {
        std::cout << except.what() << "\n";
    }
}
else if(std::is_same<T, std::string>::value) {
    auto result = _input;
    return(result);
}
else {
    std::cerr << "Unknown input type!\n";
    std::exit(1);
}
}

И я вызываю функцию в основном, как показано ниже

int main() {
std::string _input = "10";
std::cout << "Enter value:" <<  getInput<int>(_input) << '\n';
return(0);

} Это, однако, приводит к следующей ошибке.

error: no viable conversion from returned value of type 'std::__cxx11::basic_string<char>' to function return type 'int'
    return(result);

Я действительно не уверен, правильно ли я понимаю эту ошибку. Может ли кто-нибудь быть достаточно добрым, чтобы указать мне правильное направление?

Спасибо!

1 Ответ

4 голосов
/ 07 октября 2019

simple if по-прежнему требует, чтобы ветвь была действительной, даже если она не выбрана (ваша функция возвращает все int / unsigned int / float / string).

if constexprпозволяет "отбрасывать" не выбранные ветки (но требует условия времени компиляции (что у вас есть)).

template<typename T>
T getInput(std::string& _input) {
    std::cin >> _input;

    if constexpr (std::is_same<T, int>::value) {
        try{
            auto result=std::stoi(_input);
            return(result);
        }
        catch(std::invalid_argument& except) {
            std::cout << except.what() << "\n";
        }
    }
    else if constexpr (std::is_same<T, unsigned int>::value) {
        try{
            auto result=std::stoul(_input);
            return(result);
        }
        catch(std::invalid_argument& except) {
            std::cout << except.what() << "\n";
        }
    }
    // ...

}

До C ++ 17 вы должны использовать другие способы, такие как специализация, диспетчеризация тегов, .. .

template<typename T> T getInput(std::string& _input);

template<> int getInput(std::string& _input)
{
    std::cin >> _input;

    try {
        auto result=std::stoi(_input);
        return(result);
    } catch(std::invalid_argument& except) {
        std::cout << except.what() << "\n";
    }
}

template<> unsigned int getInput(std::string& _input)
{
    try{
        auto result=std::stoul(_input);
        return(result);
    } catch(std::invalid_argument& except) {
        std::cout << except.what() << "\n";
    }
}
// ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...