-1

I am using a library function which is invoked through a macro

It turns out that I cannot pass a variable using that function because, the library function must be invoked through a Macro:

 RUN_LIB1(app, url) app.run<get_parameter(url)>(url)

The problem is that get_parameter has the following signature

  template<unsigned N>
 constexpr uint64_t get_parameter_tag(char (&url)[N])

while the run method has the following signature

 run(std::string&& url)

So the Macro works fine if I do :

 RUN_LIB(app, "test")

but not when I e.g. store the compile time constructed char in a variable.. like:

 template<unsigned N> 
   call_lib(char (&url) [N]){

       RUN_LIB(app,url) // error: no matching member function for call to 'run'
     
   }
   
  call_lib("Test"); // wont compile

I am thinking on passing a std::array<char,N> to my call_lib. Then, I want to convert that std::array to a char[N] , but can that be done at compile time? Or is there any other solution to make this work.

The function get_parameter is a recursive function iterating through the size of the url

ATK
  • 1,296
  • 10
  • 26
  • Yes I am intending to invoke RUN_LIB for each url .. That is not my problem. My problem is I need to pass a url to a wrapper and then forward that to RUN_LIB. – ATK Jun 06 '22 at 16:34
  • 1
    Parameters passed to template parameter MUST be evaluated at compile time. This means `constexpr`, your parameter `url` in call_lib can't be evaluated at compile time. Size of string here is irrelevant here, unless return value of `get_parameter` in macro depends only on size of `url`! – Marek R Jun 06 '22 at 16:40
  • return value of get_parameter does depend on size of url, why is that relevant then? and what could we possibly do – ATK Jun 06 '22 at 16:46
  • You cannot do anything to determine the template parameter of `app.run` based on the function parameter (other than possibly checking for every single possible value at runtime using e.g. ite). You may get a clearer error message by changing `get_parameter` from `constexpr` to `consteval`... – fabian Jun 06 '22 at 16:53
  • Do you really mean `char` instead of `const char` here? Because then `RUN_LIB(app, "test")` doesn't work either. – user17732522 Jun 06 '22 at 16:56
  • Can you provide a [mcve]? I don't understand the fragment. What does the macro actually do? What is `run`? Why does it matter? – Barry Jun 06 '22 at 17:01

1 Answers1

3

Instead of passing const char*, pass sequence of char:

template<char... Cs> 
void call_lib(char_sequence<char, Cs...> seq){
    RUN_LIB(app, seq.c_str);
}

gcc/clang have an extension to allow to build UDL from literal string:

template<typename Char, Char... Cs>
struct char_sequence
{
    static constexpr const Char c_str[] = {Cs..., 0};
};

// That template uses the extension
template<typename Char, Char... Cs>
constexpr auto operator"" _cs() -> char_sequence<Cs...> {
    return {};
}

See my answer from String-interning at compiletime for profiling to have MAKE_STRING macro if you cannot used the extension (Really more verbose, and hard coded limit for accepted string length).

Then the call would be

call_lib("Test"_cs);
Jarod42
  • 203,559
  • 14
  • 181
  • 302