4

I am trying to create a function overload for std::bitset<N>::reference. I know this usually isn't useful since implicit conversions to/from bool already exist, but I believe it is necessary here (although I am open to other suggestions).

As an example of something similar to my use case, consider trying to overload the istream extraction operator for bitset references:

#include <bitset>
#include <iostream>

template<typename Ch, typename Tr, std::size_t N>
std::basic_istream<Ch, Tr> &operator>>(
    std::basic_istream<Ch, Tr> &is,
    typename std::bitset<N>::reference &ref)
{
    bool x;
    is >> x;
    ref = x;
    return is;
}

int main()
{
    std::bitset<4> X;
    std::cin >> X[2];
    std::cout << X[2];
}

This fails to compile for at least GCC and Clang since the compiler cannot deduce the size N.

Here are some ideas I have already considered which don't fully solve the problem:

  • Make a more generic overload and attempt to SFINAE-out unwanted instantiations. However, I am unaware of any way to definitively test whether a given type is a bitset reference and I am worried that this could lead to ambiguous overload errors in the future.
  • Use a deduction guide. However, I don't know how to obtain the value of N given only the reference type, and even if this was possible, I would prefer that the code worked in C++14.
  • Modify the STL implementation. This is not possible for my use case.
  • Implement my own bitset. I would prefer to use std::bitset if possible.

A comment on this question says this sort of thing is impossible in the general case. Is there a better way to do this than these options in the special case of std::bitset<N>::reference? Thanks in advance!

Evan Bailey
  • 168
  • 1
  • 12
  • 3
    I don't think it's possible. Moreover, overloaded operators have to be where [ADL](https://en.cppreference.com/w/cpp/language/adl) can find them (usually in the same namespace as one of the operands), otherwise they're unreliable (get shadowed easily). You should use a plain function, accepting a bitset and an index. Perhaps `std::cin >> ReadBit(bitset, 2)` if you fell fancy. – HolyBlackCat Jul 10 '23 at 22:37
  • 2
    As for the deduction: It is possible for an implementation to have a common "reference to single bit" that works for any N. So it is not only "not required" to deduce N from a nested type, it might actually be impossible. – BoP Jul 11 '23 at 07:22
  • 1
    [OT]: Avoid to overload operator when there are no user types involved. (those operator might exist in the future for example). – Jarod42 Jul 11 '23 at 11:41

0 Answers0