I am trying to extend and specialize a member function of the BitStream class from rapidCheck.
template <typename Source>
class BitStream {
public:
explicit BitStream(Source source);
/// Returns the next value of the given type with maximum size.
template <typename T>
constexpr T next();
constexpr char next();
};
template <typename Source>
BitStream<Source>::BitStream(Source source)
{}
template <typename Source>
template <typename T>
constexpr T BitStream<Source>::next() {
return T();
}
template <typename Source>
constexpr char BitStream<Source>::next() { return (char)(1); }
int main() {
BitStream<int> bs(2);
static_assert( bs.next<int>() == 0 ); // as expected
static_assert( bs.next() == 1 ); // not really a specialization
static_assert( bs.next<char>() == 1 ); // fails, but this should succeed!
}
This simplified snippet compiles, but the last assert fails, since I had not been able to really specialize next()
for T=char
. How could that be achieved?
My requirement here is that I want to be compatible to the rest of rapidcheck, so bs.next<char>()
should call the specialized version.
Thanks in advance!
You may only specialize a member template in a specialized class template like in the following reduced example:
template <typename Source>
class BitStream {
public:
explicit BitStream(Source source);
/// Returns the next value of the given type with maximum size.
template <typename T>
constexpr T next();
};
template <>
template <>
constexpr char BitStream<int>::next<char>() {
return 1;
}
int main() {
BitStream<int> bs(2);
static_assert(bs.next<char>() == 1); // succeeds
}
Suggestion. Consider implementing a custom std::basic_streambuf
instead of BitStream
and you will be able to use input streams and input operators like bs >> char_var
and bs >> int_var
instead of char_var = bs.next<char>()
and int_var = bs.next<int>()
.