I have a callable struct Foo
defined as
struct Foo {
template <typename T>
void operator()(T i) const { /* ... */ }
};
and for reasons that are out of scope I would like to statically select which type to call it with avoiding the following cumbersome notation:
Foo foo;
foo.operator()<int>(0);
foo.operator()<char>('0');
foo.operator()<char>(0); // Notice: I want to select the implementation
// so that **implicit conversions may take place**.
To this end, I'd like to implement a template member function To()
such that the above can be rewritten as:
foo.To<int>()(0);
foo.To<char>()('0');
foo.To<char>()(0);
Basically, foo.To<T>()
would return a callable object that can be used as a callback.
One way to do this can be accomplished by using lambdas:
struct Foo {
template <typename T>
void operator()(T i) const { /* ... */ }
template <typename T>
auto To() const {
return [this](T i) -> void {
return this->operator()<T>(i);
};
}
};
However, I don't really like this solution because it creates a lambda and returns it by value, whereas I'd prefer to have some sort of "static cast" of Foo
that has no computational overhead compared to a simple call to a member function. A CRTP solution can also be adopted, but it'd probably add too much boilerplate code for something that I'd expect to be much simpler to be done. What is the most efficient way to achieve the above objective?
Your assumption that there is extra overhead involved is not necessarily correct. Compilers are really good at optimizing things, and it's always worth confirming whether that's the case or not before spending time refactoring the code for what will amount to no benefit whatsoever.
Case in point:
Gcc compiles this down to
You can play around with the example live on godbolt here: https://gcc.godbolt.org/z/jv6ejYn39