How to get an instance of a class?
Everyone would answer: call its constructor
like
class_name()
Then what if the class has no default constructor?
I have a function accepting a byte buffer as argument:
template<typename BUFFER>
void fun(BUFFER& buf) {
I need to have some restrains on BUFFER
, and I choose the newest ranges
template<std::ranges::range BUFFER>
void fun(BUFFER& buf) {
And this is a byte buffer, so the return type of std::ranges::begin(buf)
should be byte
Then I added some requirments
template<std::ranges::range BUFFER>
requires std::same_as<byte, decltype(*std::ranges::begin(BUFFER()))>
void fun(BUFFER& buf) {
This is no good because we don't know whether BUFFER
has a default constructor
So, is there any solution better than the following code?
template<typename T>
struct instanceof_t {
T value;
};
template<typename T>
using instanceof = instanceof_t<T>::value;
template<std::ranges::range BUFFER>
requires std::same_as<byte, decltype(std::ranges::begin(instanceof<BUFFER>))>
void fun(BUFFER& buf) {
CodePudding user response:
There is already range_value_t
which is used to obtain the value type of the iterator type of range type R
, so in your case it should be
#include <ranges>
template<std::ranges::range BUFFER>
requires std::same_as<std::byte, std::ranges::range_value_t<BUFFER>>
void fun(BUFFER& buf);
CodePudding user response:
std::declval
can be used:
template<std::ranges::range BUFFER>
requires std::same_as<byte, decltype(std::ranges::begin(std::declval<BUFFER>()))>
void fun(BUFFER& buf)
{
// ...
}
but constraint might be really used:
template<std::ranges::range BUFFER>
requires (requires(BUFFER buf) {
{std::ranges::begin(buf) } -> std::same_as<std::byte>;
})
void fun(BUFFER& buf)
{
// ...
}