Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is there any way to pass arrays with unknown size to a lambda before C++20?

I have a macro that creates an instance of a class Info that accepts arrays with templated size as constructor arguments. The size information is used for checks.

I would like to do a check in this macro before returning the instance. The check could be something like a static_assert, but let’s leave that open here. An elegant way to do the check is to make the macro call a lambda that performs the check(s) and then returns the instance.

But this fails because of a very annoying reason: if I pass char arrays to an auto argument of the lambda, they are deduces as char pointers and this prevents calling the Info constructor. So I would like to pass char arrays with templated size to the lambda. But this is only possible from C++20 on.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Is there any workaround? Can I make a lambda accept arrays of templated size with C++ 17?

Code:

#include <cstdlib>
#include <iostream>

class Info
{
  public:
    template <size_t function_length, size_t file_length>
    Info(const char (&function)[function_length], const char (&file)[file_length])
        : function(function)
        , file(file)
    {
        if ('\0' != function[function_length - 1])
        {
            this->function = "invalid";
        }

        if ('\0' != file[file_length - 1])
        {
            this->file = "invalid";
        }
    }

    const char* function;
    const char* file;
};

#define CREATE_INFO()                                                                                                  \
    (                                                                                                                  \
        []<std::size_t function_length, std::size_t file_length>(                                                      \
            const auto(&function)[function_length], const auto(&file)[file_length])                                    \
        {                                                                                                              \
            static constexpr char error_string[] = "invalid";                                                          \
                                                                                                                       \
            if ('m' != function[0])                                                                                    \
            {                                                                                                          \
                return Info(error_string, error_string);                                                               \
            }                                                                                                          \
            return Info(function, file);                                                                               \
        }(__FUNCTION__, __FILE__))

int main()
{
    Info info = CREATE_INFO();

    std::cout << "Function: " << info.function << ", file: " << info.file << std::endl;

    return 0;
}

Example in Compiler Explorer: https://godbolt.org/z/8q5zYKj4a

>Solution :

Simply delete the template parts and take the variables by const&:

[](const auto&function, const auto&file) \
{ \
  static constexpr char error_string[] = "invalid"; \
  if ('m' != function[0]) { \
    return Info(error_string, error_string); \
  } \
  return Info(function, file); \
}(__FUNCTION__, __FILE__)

decay-to-pointer only happens if you convert to a value (bare auto include). The type of function in the above will be some reference-to-array (and same for file).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading