I'd like to replace a std::function with a template parameter, since everything is known at compile time. No I know there a many answers here in the forum and over the internet how to pass and directly consume a templated function (for ex here https://rules.sonarsource.com/cpp/RSPEC-5213/?search=std%3A%3Afunction)
However in my case: I am using the templated function in a private member. Therefore I have to set up the templated function within the constructor.
Now I have 2 questions:
how can I pass and store the templated function as a member parameter for later use in a private function
is it possible to use concepts to enforce that all functions passed as a template argument are using a specific signature (in my case std::string(const uint32_t u32ReadOffset, const uint32_t u32MaxReadLength)
)
So far i have come up with this
#include <string_view>
#include <concepts>
#include <string>
#include <cstdint>
template <typename T, typename U, typename V>
concept IDmmy = requires(T a, const std::string_view b)
{
{ a.template foo<U>() };
{ a.template bar<V>(b) };
};
template<typename FnGetFunction_T>
class Foo
{
public:
explicit Foo(FnGetFunction_T fn);
void publicFunction();
private:
FnGetFunction_T m_fn;
void privateFunction();
};
template<typename FnGetFunction_T>
Foo<FnGetFunction_T>::Foo(FnGetFunction_T fn):
m_fn(fn)
{
}
template<typename FnGetFunction_T>
void Foo<FnGetFunction_T>::publicFunction()
{
//do some checking first
//call private function
privateFunction();
}
template<typename FnGetFunction_T>
void Foo<FnGetFunction_T>::privateFunction()
{
//collect some internal data
std::string strRes = m_fn(0,0);
//do something with strRes
}
static std::string DummyRead(const uint32_t u32Offset, uint32_t u32MaxReadLength)
{
if(0 != u32Offset && 0 != u32MaxReadLength)
{
//avoid compiler warning in this mock
}
return "";
}
int main()
{
Foo<decltype(DummyRead)> foo = Foo<decltype(DummyRead)>(DummyRead);
return 0;
}
https://coliru.stacked-crooked.com/
Unfortunately this gives me a compiler error invalidly declared function type. Could you help me how to fix this?
Also is it possible to enforce which concepts that FnGetFunction_T always looks like this
std::string(const uint32_t u32Offset, uint32_t u32MaxReadLength)
?
thx once again guys for your help :)
Functions are not like other objects. When you pass a function as arugment you pass a function pointer not the function itself.
If you fix that:
Foo<decltype(&DummyRead)> foo = Foo<decltype(&DummyRead)>(DummyRead);
The code compiles: https://godbolt.org/z/Tv1ceqYzs
However, with Class Template Argument Deduction (CTAD) and making use of function to pointer to function decay it simply becomes:
Foo foo = Foo(DummyRead);
Also is it possible to enforce which concepts that FnGetFunction_T always looks like this std::string(const uint32_t u32Offset, uint32_t u32MaxReadLength) ?
If that is what you want then there is no point in making the type of the function a template argument in the first place. You can use usign function_type = std::string(uint32_t,uint32_t)
as the type of the function.