Home > front end >  How to get an instance of class in const expressions (decltype, templates ...)
How to get an instance of class in const expressions (decltype, templates ...)

Time:03-23

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)
{
   // ...
}
  • Related