-1

I want to make in/out functions not to write format specifiers many times. (I don't want to use cin/cout functions as possible, because they run slowly.)

So, I write this code.

If there are "int_fast16_t i" and "string s," I expect: {scanf(%d, i); cin >> s;} == {in() >> i >> s;}

struct in
{
    template<typename typ> in& operator>>(typ& val) { std::cin >> val; return *this; }
    in& operator>>(char& val) { std::scanf(" %c", &val); return *this; }
    in& operator>>(std::int_fast8_t& val) { std::scanf("%" SCNdFAST8, &val); return *this; }
    in& operator>>(std::uint_fast8_t& val) { std::scanf("%" SCNuFAST8, &val); return *this; }
    in& operator>>(std::int_fast16_t& val) { std::scanf("%" SCNdFAST16, &val); return *this; }
    in& operator>>(std::uint_fast16_t& val) { std::scanf("%" SCNuFAST16, &val); return *this; }
    in& operator>>(std::int_fast32_t& val) { std::scanf("%" SCNdFAST32, &val); return *this; }
    in& operator>>(std::uint_fast32_t& val) { std::scanf("%" SCNuFAST32, &val); return *this; }
    in& operator>>(std::int_fast64_t& val) { std::scanf("%" SCNdFAST64, &val); return *this; }
    in& operator>>(std::uint_fast64_t& val) { std::scanf("%" SCNuFAST64, &val); return *this; }
    in& operator>>(float& val) { std::scanf("%f", &val); return *this; }
    in& operator>>(double& val) { std::scanf("%lf", &val); return *this; }
};

struct out
{
    template<typename typ> template<> out& operator<<(typ& val) { std::cout << val; return *this; }
    out& operator<<(char& val) { std::printf("%c", val); return *this; }
    out& operator<<(std::int_fast8_t& val) { std::printf("%" PRIdFAST8, val); return *this; }
    out& operator<<(std::uint_fast8_t& val) { std::printf("%" PRIuFAST8, val); return *this; }
    out& operator<<(std::int_fast16_t& val) { std::printf("%" PRIdFAST16, val); return *this; }
    out& operator<<(std::uint_fast16_t& val) { std::printf("%" PRIuFAST16, val); return *this; }
    out& operator<<(std::int_fast32_t& val) { std::printf("%" PRIdFAST32, val); return *this; }
    out& operator<<(std::uint_fast32_t& val) { std::printf("%" PRIuFAST32, val); return *this; }
    out& operator<<(std::int_fast64_t& val) { std::printf("%" PRIdFAST64, val); return *this; }
    out& operator<<(std::uint_fast64_t& val) { std::printf("%" PRIuFAST64, val); return *this; }
    out& operator<<(float& val) { std::printf("%f", val); return *this; }
    out& operator<<(double& val) { std::printf("%lf", val); return *this; }
};

However, it causes errors.

error: 'in& in::operator>>(int_fast32_t&)' cannot be overloaded with 'in& in::operator>>(int_fast16_t&)'
note: previous declaration 'in& in::operator>>(int_fast16_t&)'
error: 'in& in::operator>>(uint_fast32_t&)' cannot be overloaded with 'in& in::operator>>(uint_fast16_t&)'
note: previous declaration 'in& in::operator>>(uint_fast16_t&)'
error: 'in& in::operator>>(int_fast64_t&)' cannot be overloaded with 'in& in::operator>>(int_fast16_t&)'
note: previous declaration 'in& in::operator>>(int_fast16_t&)'
error: 'in& in::operator>>(uint_fast64_t&)' cannot be overloaded with 'in& in::operator>>(uint_fast16_t&)'
note: previous declaration 'in& in::operator>>(uint_fast16_t&)'   ...(other similar error)

Are int_fast16_t, int_fast32_t and int_fast64_t the same? If so, what should I rewrite to make correct functions?

  • Maybe [this](https://stackoverflow.com/questions/31162367/significance-of-ios-basesync-with-stdiofalse-cin-tienull) is the better alternative? – Aconcagua Dec 29 '18 at 10:43

1 Answers1

4

The issue is that the various int_fastNN_t are implementation-specific typedefs that may map to the same thing so cannot be used for overloads.

Instead you should overload on the fundamental types signed char, short int, int, long int, long long int and the equivalent unsigned ones.

  • I hear that bits of 'int' depends on application execution environment, so I want to use 'int_fastNN_t'. Is there a way to implement it using "a"? – underscore Dec 29 '18 at 12:17
  • 1
    You should *define* your overloads based on the fundamental types, but you can *call* them with the `int_fastNN_t` types. The compiler will map `int_fastNN_t` to whatever the appropriate type is and pick the appropriate overload. –  Dec 29 '18 at 12:23
  • 1
    @underscore -- to be clear: the `int_xxx_t` types are all **typedefs** for built-in types. As long as you've overloaded for all the built-in types, the `int_xxx_t` types are all covered. – Pete Becker Dec 29 '18 at 14:21
  • @Pete Becker That makes sense. Thanks :) – underscore Dec 30 '18 at 02:49