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?
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ę :). –
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