7

Piszę bibliotekę z wieloma obiektami funkcji, których klasy mają kilka przeciążeń operator(), które nie zależą od stanu klas i nie zmieniają go. Teraz próbowałem sprawić, aby mój kod działał z wieloma API w starym stylu (nie jest to przypadkowa potrzeba, faktycznie musiałem radzić sobie z takimi API) i dlatego postanowiłem uczynić obiekty funkcji wymiennymi dowolnymi wskaźnikami funkcji odpowiadającymi jednemu z przeciążenia. W pewnym momencie zdałem sobie sprawę, że mam zbyt wiele takich konwersji do obsługi operatorów wskaźnikowych i że teoretycznie powinienem móc napisać jednego operatora konwersji variadic. Tutaj jest klasa wdrożenia takiego operatora o zmiennej liczbie argumentów:Konwersja wskaźnika funkcji Variadic

struct foobar 
{ 
    template<typename... Args> 
    using fptr_t = void(*)(Args... args); 

    template<typename... Args> 
    operator fptr_t<Args...>() const 
    { 
     return [](Args... args) { 
      // Whatever 
     }; 
    } 
}; 

Jak widać, użyłem konwersję lambda funkcjonować wskaźnik wdrożyć operatora konwersji, która nie jest to problem, ponieważ każdy obiekt funkcji mam jest bezpaństwowcem. Celem było, aby móc korzystać z klasy następująco:

int main() 
{ 
    void(*foo)(int) = foobar(); 
    void(*bar)(float, double) = foobar(); 
} 

g ++ nie ma problemu kompilacji tego kodu z oczekiwanymi semantyki. Jednakże, dzyń ++ rejects it z błędem awarii podstawienie szablonu:

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. 

Zauważ, że dzyń ++ nie ma problemu z takich operatorów konwersji tak długo, jak są zaangażowane żadne szablony o zmiennej liczbie argumentów. Jeśli użyję pojedynczego parametru szablonu, nie będzie miał problemu ze skompilowaniem kodu. Teraz, czy powyższy kod zostanie zaakceptowany lub odrzucony przez kompilator?

+4

myślę tego [samo jak ten bug] (https: // llvm.org/bugs/show_bug.cgi?id=24032). Istnieje również powiązane pytanie dotyczące SO. Richard Smith [mówi o błędzie] (http://stackoverflow.com/questions/31225888/pre-typedefing-a-variadic-function-pointer-argument #comment50471304_31225888), więc mu wierzę :). –

+0

Obejście: przekonwertować za pomocą operatora 'template F *()', dodać test sfinae, że jest to typ funkcji, wyodrębnić argumenty za pomocą cech, rozpakować za pomocą pomocnika, użyć pomocnika do konwersji na wskaźnik? – Yakk

Odpowiedz

1

Lambda może zostać przekształcona w wskaźnik funkcji tylko wtedy, gdy nie jest przechwytywana, więc kod powinien działać. Jest to uzasadnione w standardowych 5.1.2/P6 wyrażeń lambda [expr.prim.lambda] (podkr):

The closure type for a non-generic lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function with C++ language linkage (7.5) having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.

Więc chciałbym przedstawić ją jako błąd dzyń.

Jako pracy wokół dla dzyń, można przekonwertować go do std::function jak pokazano poniżej:

struct foobar 
{ 
    template<typename... Args> 
    using fptr_t = void(*)(Args... args); 

    template<typename... Args> 
    operator std::function<void(Args...)>() const 
    { 
     return [](Args... args) { 
      //... 
     }; 
    } 
}; 

int main() 
{ 
    std::function<void(int)> f1 = foobar(); 
    std::function<void(double, float)> f2 = foobar(); 
    f1(1); 
    f2(2.0, 1.0f); 
} 

Live Demo

+0

Cóż, tak, znam to wszystko. Chodzi mi o to, że nie pytam o rozwiązanie mojego problemu (pracowałem już nad tym przez jakiś czas). Pytam tylko o odpowiedź językowo-prawnika, aby wiedzieć, do którego kompilatora prześlę zgłoszenie błędu: p – Morwenn

+0

@Morwenn zgłosisz zgłoszenie błędu do CLANG: P. – 101010

Powiązane problemy