-2

this line of code is wrong and won't compile but i am wondering if it can be fixed.

#include <iostream>

template <typename T>

auto getValue()
{
    std::cout << "Enter an integral value: ";
    T value{};
    std::cin >> value;
    // I would do input handing later
    return value;
}

int main()
{
    auto value1{getValue()};
    std::cout << value1 << '\n';
}

please point out if there is a way to make it possible or if it is not possible then why?

thank you.

I want to receive an integral value from the user and create a variable depending on the value that they entered.

for example if they entered 56 then an integer variable will be created. and if they entered 56.78 then a double variable will be created since it is a lateral.

user17732522
  • 53,019
  • 2
  • 56
  • 105
kitshaar
  • 11
  • 1
  • 3
    There is no way for the compiler to know what type you want to have. What the user types cannot determine a type. So you need to call `getValue()` or similar to tell what type you want. – user17732522 Aug 16 '23 at 07:22
  • 6
    "_for example if they entered 56 then an integer variable will be created_": How do you know that `56` should be an integer rather than a string? How do you know that it won't be followed by `.123`, so that it "should" be a `double`? It is impossible. – user17732522 Aug 16 '23 at 07:23
  • 4
    And all of that aside, types are fixed at compile-time. The type of a variable can't depend on what the user types. – user17732522 Aug 16 '23 at 07:25
  • 1
    by the time you call `getValue` the parameter `T` must already be known. In general it is not trivial to decide for a type based on user input. How do you distinguish between a string `3` and the integer `3` for example? – 463035818_is_not_an_ai Aug 16 '23 at 07:28
  • @user17732522 hmm, (nod). thnx for pointing out the underlying problems. – kitshaar Aug 16 '23 at 07:30
  • you expect magic and the issue about `auto` and the template is secondary as long as you cannot tell what input should result in what type (because there is no obvious way to do that) – 463035818_is_not_an_ai Aug 16 '23 at 07:33
  • fwiw, it is possible to get a `int` from `3` and a `double` from `3.0` and a `std::string` from `three`, just not automatically, its code you have to write (or use some library) – 463035818_is_not_an_ai Aug 16 '23 at 07:35
  • @463035818_is_not_an_ai I am understanding my mistake, the thing is i wanted to make a sum funtion that take 2 template parameters and return the sum. for example, if the user provides 5 and 4 tnen output is 9 and if user provides 5 and 4.2 then output is 9.2.(floating addition). – kitshaar Aug 16 '23 at 07:37
  • "i wanted to make a sum funtion" thats a very different problem. And it is much simpler: `auto sum(auto a,auto b) { return a+b;}`. The built-in `+` already works the way you want. Though you need the right type for `a` and `b` before you call that function – 463035818_is_not_an_ai Aug 16 '23 at 07:40
  • @463035818_is_not_an_ai do i have to get the value using double and then pass it to the sum function? template auto sum (T value1, U value2){ return value1+value2; } – kitshaar Aug 16 '23 at 07:42

1 Answers1

1

Types are fixed at compile time so your code can't work. If you really need to do this then there are a few approaches.

  1. The javascript approach of just using double everywhere, a double can hold 53 bit integers without losing precision.
  2. Return a std::variant

Option 2 could look something like this:

#include <variant>
#include <iostream>
#include <string>
#include <optional>

std::optional<int> parseInt(const std::string& str)
{
    try
    {
        size_t pos;
        int value = std::stoi(str, &pos);
        if (pos == str.size())
        {
            return value;
        }
    }
    catch (std::exception&)
    {
    }
    return {};
}

std::optional<double> parseDouble(const std::string& str)
{
    try
    {
        size_t pos;
        double value = std::stod(str, &pos);
        if (pos == str.size())
        {
            return value;
        }
    }
    catch (std::exception&)
    {
    }
    return {};
}
std::variant<int, double> getValue()
{
  while (true)
  {
    std::cout << "Enter a numerical value: ";
    std::string str;
    std::getline(std::cin, str);
    auto i = parseInt(str);
    if (i)
    {
        return *i;
    }
    auto d = parseDouble(str);
    if (d)
    {
        return *d;
    }
    throw std::invalid_argument("invalid input");
  }
}
Alan Birtles
  • 32,622
  • 4
  • 31
  • 60