2017-02-13 28 views
6

Biorąc pod uwagę następujące zmiennej liczbie argumentów szablonu:Szablon odliczenie dla zmiennej liczbie argumentów szablonu argumentów lambda

template<typename... Params> 
void fun(void(*f)(Params...), Params... params) { 
    f(params...); 
} 

int main() { 
    fun(+[](int a, int b) {}, 2, 3); 
} 

Na razie podczas wywoływania fun z lambda trzeba określić typy wszystkich argumentów lambda wyraźnie. Wydaje się zbędne, ponieważ int, int można wywnioskować z 2, 3. Czy istnieje sposób, aby uczynić go bardziej zwięzłym i automatycznym?

Chciałbym następujących do pracy, ale nie:

template<typename... Params> 
void fun(void(*f)(Params...), Params... params) { 
    f(params...); 
} 

int main() { 
    fun(+[](auto a, auto b) {}, 2, 3); 
} 

Mam kompilacji z g++ 5.4.0 i -std=c++14.

+1

Masz problem z wpisaniem 'int' zamiast' auto'? – Brian

+0

@Brian Tak, bo wymaga ode mnie wywnioskowania, że ​​jest to "int". Może być cokolwiek dłuższego, aby uczynić go bardziej dramatycznym. –

Odpowiedz

3

Weźmy funkcję T zamiast przez wskaźnik:

template<typename T, typename... Params> 
void fun(T f, Params... params) { 
    f(params...); 
} 

int main() { 
    fun([](auto a, auto b) {}, 2, 3); 
} 

ten sposób kompilator może wybrać, które przeciążenie jest prawo zadzwonić w miejscu połączenia zamiast jeśli wewnątrz operatora +. Jak wspomniano w komentarzu, nie ma żadnego operatora zdefiniowanego dla standardowych lambdas.


Alternatywnie, można wyłączyć kompilator od próbując wydedukować Params od wskaźnika funkcji za pomocą aliasu tożsamości, ale naprawdę nie polecam go. W każdym razie, tutaj:

template<typename T> 
struct identity { using type = T; }; 

template<typename T> 
using identity_t = typename identity<T>::type; 

template<typename... Params> 
void fun(void(*f)(identity_t<Params>...), Params... params) { 
    f(params...); 
} 

int main() { 
    // v----- no unary +. That operator is not defined for generic lambdas. 
    fun([](auto a, auto b) {}, 2, 3); 
} 
+0

Należy zauważyć, że nie ma operatora '+' dla nietypowych lambd. Wbudowany operator '+' jest używany, ale lambda jest w ten sposób wymuszona na wskaźnik za pomocą swojego operatora konwersji do wskaźnika funkcji. – Brian

Powiązane problemy