I am writing a library with many function objects whose classes have several operator() overloads that are independent of the state of the classes and do not change it. Now I was trying to get my code to work with many old-style APIs (this is not a random necessity, I actually had to deal with such APIs), and therefore decided to turn the function objects into quotes with any function pointer matching one out of overload. At some point, I realized that I have too many of these transformations for pointer operators to work, and that I would theoretically have to write one variational transform operator. Here is a class that implements such a variational operator:
struct foobar { template<typename... Args> using fptr_t = void(*)(Args... args); template<typename... Args> operator fptr_t<Args...>() const { return [](Args... args) {
As you can see, I used the conversion of lambda to a function pointer to implement the conversion operator, which is not a problem, since every function object that I have has no state. The goal was to use the class as follows:
int main() { void(*foo)(int) = foobar(); void(*bar)(float, double) = foobar(); }
g ++ has no problem compiling this code with the expected semantics. However, clang ++ rejects it with a pattern replacement replacement error:
main.cpp:21:11: error: no viable conversion from 'foobar' to 'void (*)(int)' void(*foo)(int) = foobar(); ^ ~~~~~~~~ main.cpp:11:5: note: candidate function [with Args = int] operator fptr_t<Args...>() const ^ 1 error generated.
Please note that clang ++ has no problems with such conversion operators if variational patterns are not involved. If I use one parameter of the template, it will have no problems compiling the code. Now, should the code be accepted or rejected by the compiler?
c ++ language-lawyer c ++ 14 function-pointers variadic-templates
Morwenn
source share